OLD | NEW |
1 // Copyright 2014 The Go Authors. All rights reserved. | 1 // Copyright 2014 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Table-driven decoding of x86 instructions. | 5 // Table-driven decoding of x86 instructions. |
6 | 6 |
7 package x86asm | 7 package x86asm |
8 | 8 |
9 import ( | 9 import ( |
10 "encoding/binary" | 10 "encoding/binary" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 } | 177 } |
178 p := Prefix(b) | 178 p := Prefix(b) |
179 switch p { | 179 switch p { |
180 case PrefixDataSize: | 180 case PrefixDataSize: |
181 if mode == 16 { | 181 if mode == 16 { |
182 p = PrefixData32 | 182 p = PrefixData32 |
183 } else { | 183 } else { |
184 p = PrefixData16 | 184 p = PrefixData16 |
185 } | 185 } |
186 case PrefixAddrSize: | 186 case PrefixAddrSize: |
187 » » if mode == 16 { | 187 » » if mode == 32 { |
| 188 » » » p = PrefixAddr16 |
| 189 » » } else { |
188 p = PrefixAddr32 | 190 p = PrefixAddr32 |
189 } else { | |
190 p = PrefixAddr16 | |
191 } | 191 } |
192 } | 192 } |
193 » return Inst{Prefix: Prefixes{p}}, 1, nil | 193 » // Note: using composite literal here confuses 'bundle' tool. |
| 194 » inst := Inst{} |
| 195 » inst.Prefix = Prefixes{p} |
| 196 » return inst, 1, nil |
194 } | 197 } |
195 | 198 |
196 // truncated reports a truncated instruction. | 199 // truncated reports a truncated instruction. |
197 // For now we use instPrefix but perhaps later we will return | 200 // For now we use instPrefix but perhaps later we will return |
198 // a specific error here. | 201 // a specific error here. |
199 func truncated(src []byte, mode int) (Inst, int, error) { | 202 func truncated(src []byte, mode int) (Inst, int, error) { |
200 // return Inst{}, len(src), ErrTruncated | 203 // return Inst{}, len(src), ErrTruncated |
201 return instPrefix(src[0], mode) // too long | 204 return instPrefix(src[0], mode) // too long |
202 } | 205 } |
203 | 206 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 // prefix decoding information | 251 // prefix decoding information |
249 pos = 0 // position reading src | 252 pos = 0 // position reading src |
250 nprefix = 0 // number of prefixes | 253 nprefix = 0 // number of prefixes |
251 lockIndex = -1 // index of LOCK prefix in src and inst.Pre
fix | 254 lockIndex = -1 // index of LOCK prefix in src and inst.Pre
fix |
252 repIndex = -1 // index of REP/REPN prefix in src and inst
.Prefix | 255 repIndex = -1 // index of REP/REPN prefix in src and inst
.Prefix |
253 segIndex = -1 // index of Group 2 prefix in src and inst.
Prefix | 256 segIndex = -1 // index of Group 2 prefix in src and inst.
Prefix |
254 dataSizeIndex = -1 // index of Group 3 prefix in src and inst.
Prefix | 257 dataSizeIndex = -1 // index of Group 3 prefix in src and inst.
Prefix |
255 addrSizeIndex = -1 // index of Group 4 prefix in src and inst.
Prefix | 258 addrSizeIndex = -1 // index of Group 4 prefix in src and inst.
Prefix |
256 rex Prefix // rex byte if present (or 0) | 259 rex Prefix // rex byte if present (or 0) |
257 rexUsed Prefix // bits used in rex byte | 260 rexUsed Prefix // bits used in rex byte |
| 261 rexIndex = -1 // index of rex byte |
258 | 262 |
259 addrMode = mode // address mode (width in bits) | 263 addrMode = mode // address mode (width in bits) |
260 dataMode = mode // operand mode (width in bits) | 264 dataMode = mode // operand mode (width in bits) |
261 | 265 |
262 // decoded ModR/M fields | 266 // decoded ModR/M fields |
263 haveModrm bool | 267 haveModrm bool |
264 modrm int | 268 modrm int |
265 mod int | 269 mod int |
266 regop int | 270 regop int |
267 rm int | 271 rm int |
(...skipping 13 matching lines...) Expand all Loading... |
281 imm int64 | 285 imm int64 |
282 imm8 int8 | 286 imm8 int8 |
283 immc int64 | 287 immc int64 |
284 | 288 |
285 // output | 289 // output |
286 opshift int | 290 opshift int |
287 inst Inst | 291 inst Inst |
288 narg int // number of arguments written to inst | 292 narg int // number of arguments written to inst |
289 ) | 293 ) |
290 | 294 |
| 295 if mode == 64 { |
| 296 dataMode = 32 |
| 297 } |
| 298 |
291 // Prefixes are certainly the most complex and underspecified part of | 299 // Prefixes are certainly the most complex and underspecified part of |
292 // decoding x86 instructions. Although the manuals say things like | 300 // decoding x86 instructions. Although the manuals say things like |
293 // up to four prefixes, one from each group, nearly everyone seems to | 301 // up to four prefixes, one from each group, nearly everyone seems to |
294 // agree that in practice as many prefixes as possible, including multip
le | 302 // agree that in practice as many prefixes as possible, including multip
le |
295 // from a particular group or repetitions of a given prefix, can be used
on | 303 // from a particular group or repetitions of a given prefix, can be used
on |
296 // an instruction, provided the total instruction length including prefi
xes | 304 // an instruction, provided the total instruction length including prefi
xes |
297 // does not exceed the agreed-upon maximum of 15 bytes. | 305 // does not exceed the agreed-upon maximum of 15 bytes. |
298 // Everyone also agrees that if one of these prefixes is the LOCK prefix | 306 // Everyone also agrees that if one of these prefixes is the LOCK prefix |
299 // and the instruction is not one of the instructions that can be used w
ith | 307 // and the instruction is not one of the instructions that can be used w
ith |
300 // the LOCK prefix or if the destination is not a memory operand, | 308 // the LOCK prefix or if the destination is not a memory operand, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 dataMode = 16 | 378 dataMode = 16 |
371 p = PrefixData16 | 379 p = PrefixData16 |
372 } | 380 } |
373 if dataSizeIndex >= 0 { | 381 if dataSizeIndex >= 0 { |
374 inst.Prefix[dataSizeIndex] |= PrefixIgnored | 382 inst.Prefix[dataSizeIndex] |= PrefixIgnored |
375 } | 383 } |
376 dataSizeIndex = pos | 384 dataSizeIndex = pos |
377 | 385 |
378 // Group 4 - address size override | 386 // Group 4 - address size override |
379 case 0x67: | 387 case 0x67: |
380 » » » if mode == 16 { | 388 » » » if mode == 32 { |
381 » » » » addrMode = 32 | |
382 » » » » p = PrefixAddr32 | |
383 » » » } else if mode == 32 { | |
384 addrMode = 16 | 389 addrMode = 16 |
385 p = PrefixAddr16 | 390 p = PrefixAddr16 |
386 » » » } else if mode == 64 { | 391 » » » } else { |
387 addrMode = 32 | 392 addrMode = 32 |
388 p = PrefixAddr32 | 393 p = PrefixAddr32 |
389 } | 394 } |
390 if addrSizeIndex >= 0 { | 395 if addrSizeIndex >= 0 { |
391 inst.Prefix[addrSizeIndex] |= PrefixIgnored | 396 inst.Prefix[addrSizeIndex] |= PrefixIgnored |
392 } | 397 } |
393 addrSizeIndex = pos | 398 addrSizeIndex = pos |
394 } | 399 } |
395 | 400 |
396 if pos >= len(inst.Prefix) { | 401 if pos >= len(inst.Prefix) { |
397 return instPrefix(src[0], mode) // too long | 402 return instPrefix(src[0], mode) // too long |
398 } | 403 } |
399 | 404 |
400 inst.Prefix[pos] = p | 405 inst.Prefix[pos] = p |
401 } | 406 } |
402 | 407 |
403 // Read REX prefix. | 408 // Read REX prefix. |
404 if pos < len(src) && mode == 64 && Prefix(src[pos]).IsREX() { | 409 if pos < len(src) && mode == 64 && Prefix(src[pos]).IsREX() { |
405 rex = Prefix(src[pos]) | 410 rex = Prefix(src[pos]) |
| 411 rexIndex = pos |
| 412 if pos >= len(inst.Prefix) { |
| 413 return instPrefix(src[0], mode) // too long |
| 414 } |
| 415 inst.Prefix[pos] = rex |
406 pos++ | 416 pos++ |
407 if rex&PrefixREXW != 0 { | 417 if rex&PrefixREXW != 0 { |
408 dataMode = 64 | 418 dataMode = 64 |
| 419 if dataSizeIndex >= 0 { |
| 420 inst.Prefix[dataSizeIndex] |= PrefixIgnored |
| 421 } |
409 } | 422 } |
410 } | 423 } |
411 | 424 |
412 // Decode instruction stream, interpreting decoding instructions. | 425 // Decode instruction stream, interpreting decoding instructions. |
413 // opshift gives the shift to use when saving the next | 426 // opshift gives the shift to use when saving the next |
414 // opcode byte into inst.Opcode. | 427 // opcode byte into inst.Opcode. |
415 opshift = 24 | 428 opshift = 24 |
416 if decoderCover == nil { | 429 if decoderCover == nil { |
417 decoderCover = make([]bool, len(decoder)) | 430 decoderCover = make([]bool, len(decoder)) |
418 } | 431 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 mem = addr16[rm] | 473 mem = addr16[rm] |
461 if rm == 6 && mod == 0 { | 474 if rm == 6 && mod == 0 { |
462 mem.Base = 0 | 475 mem.Base = 0 |
463 } | 476 } |
464 | 477 |
465 // Consume disp16 if present. | 478 // Consume disp16 if present. |
466 if mod == 0 && rm == 6 || mod == 2 { | 479 if mod == 0 && rm == 6 || mod == 2 { |
467 if pos+2 > len(src) { | 480 if pos+2 > len(src) { |
468 return truncated(src, mo
de) | 481 return truncated(src, mo
de) |
469 } | 482 } |
470 » » » » » » mem.Disp = int32(binary.LittleEn
dian.Uint16(src[pos:])) | 483 » » » » » » mem.Disp = int64(binary.LittleEn
dian.Uint16(src[pos:])) |
471 pos += 2 | 484 pos += 2 |
472 } | 485 } |
473 | 486 |
474 // Consume disp8 if present. | 487 // Consume disp8 if present. |
475 if mod == 1 { | 488 if mod == 1 { |
476 if pos >= len(src) { | 489 if pos >= len(src) { |
477 return truncated(src, mo
de) | 490 return truncated(src, mo
de) |
478 } | 491 } |
479 » » » » » » mem.Disp = int32(int8(src[pos])) | 492 » » » » » » mem.Disp = int64(int8(src[pos])) |
480 pos++ | 493 pos++ |
481 } | 494 } |
482 } | 495 } |
483 } else { | 496 } else { |
484 haveMem = mod != 3 | 497 haveMem = mod != 3 |
485 | 498 |
486 // 32-bit or 64-bit form | 499 // 32-bit or 64-bit form |
487 // Consume SIB encoding if present. | 500 // Consume SIB encoding if present. |
488 if rm == 4 && mod != 3 { | 501 if rm == 4 && mod != 3 { |
489 haveSIB = true | 502 haveSIB = true |
(...skipping 17 matching lines...) Expand all Loading... |
507 rexUsed |= PrefixREXX | 520 rexUsed |= PrefixREXX |
508 index |= 8 | 521 index |= 8 |
509 } | 522 } |
510 | 523 |
511 mem.Scale = 1 << uint(scale) | 524 mem.Scale = 1 << uint(scale) |
512 if index == 4 { | 525 if index == 4 { |
513 // no mem.Index | 526 // no mem.Index |
514 } else { | 527 } else { |
515 mem.Index = baseRegForBits(addrM
ode) + Reg(index) | 528 mem.Index = baseRegForBits(addrM
ode) + Reg(index) |
516 } | 529 } |
517 » » » » » if base == 5 && mod == 0 { | 530 » » » » » if base&7 == 5 && mod == 0 { |
518 // no mem.Base | 531 // no mem.Base |
519 } else { | 532 } else { |
520 mem.Base = baseRegForBits(addrMo
de) + Reg(base) | 533 mem.Base = baseRegForBits(addrMo
de) + Reg(base) |
521 } | 534 } |
522 } else { | 535 } else { |
523 if rex&PrefixREXB != 0 { | 536 if rex&PrefixREXB != 0 { |
524 rexUsed |= PrefixREXB | 537 rexUsed |= PrefixREXB |
525 rm |= 8 | 538 rm |= 8 |
526 } | 539 } |
527 | 540 » » » » » if mod == 0 && rm&7 == 5 || rm&7 == 4 { |
528 » » » » » if mod == 0 && rm == 5 || rm == 4 { | |
529 // base omitted | 541 // base omitted |
530 } else if mod != 3 { | 542 } else if mod != 3 { |
531 mem.Base = baseRegForBits(addrMo
de) + Reg(rm) | 543 mem.Base = baseRegForBits(addrMo
de) + Reg(rm) |
532 } | 544 } |
533 } | 545 } |
534 | 546 |
535 // Consume disp32 if present. | 547 // Consume disp32 if present. |
536 » » » » if mod == 0 && (rm == 5 || haveSIB && base == 5)
|| mod == 2 { | 548 » » » » if mod == 0 && (rm&7 == 5 || haveSIB && base&7 =
= 5) || mod == 2 { |
537 if pos+4 > len(src) { | 549 if pos+4 > len(src) { |
538 return truncated(src, mode) | 550 return truncated(src, mode) |
539 } | 551 } |
540 » » » » » mem.Disp = int32(binary.LittleEndian.Uin
t32(src[pos:])) | 552 » » » » » mem.Disp = int64(binary.LittleEndian.Uin
t32(src[pos:])) |
541 pos += 4 | 553 pos += 4 |
542 } | 554 } |
543 | 555 |
544 // Consume disp8 if present. | 556 // Consume disp8 if present. |
545 if mod == 1 { | 557 if mod == 1 { |
546 if pos >= len(src) { | 558 if pos >= len(src) { |
547 return truncated(src, mode) | 559 return truncated(src, mode) |
548 } | 560 } |
549 » » » » » mem.Disp = int32(int8(src[pos])) | 561 » » » » » mem.Disp = int64(int8(src[pos])) |
550 pos++ | 562 pos++ |
551 } | 563 } |
| 564 |
| 565 // In 64-bit, mod=0 rm=5 is PC-relative instead
of just disp. |
| 566 // See Vol 2A. Table 2-7. |
| 567 if mode == 64 && mod == 0 && rm&7 == 5 { |
| 568 if addrMode == 32 { |
| 569 mem.Base = EIP |
| 570 } else { |
| 571 mem.Base = RIP |
| 572 } |
| 573 } |
552 } | 574 } |
553 | 575 |
554 if segIndex >= 0 { | 576 if segIndex >= 0 { |
555 mem.Segment = prefixToSegment(inst.Prefix[segInd
ex]) | 577 mem.Segment = prefixToSegment(inst.Prefix[segInd
ex]) |
556 } | 578 } |
557 } | 579 } |
558 | 580 |
559 // Execute single opcode. | 581 // Execute single opcode. |
560 switch decodeOp(x) { | 582 switch decodeOp(x) { |
561 default: | 583 default: |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 if dataSizeIndex >= 0 { | 655 if dataSizeIndex >= 0 { |
634 inst.Prefix[dataSizeIndex] |= PrefixImpl
icit | 656 inst.Prefix[dataSizeIndex] |= PrefixImpl
icit |
635 } | 657 } |
636 pc = int(decoder[pc]) | 658 pc = int(decoder[pc]) |
637 case 32: | 659 case 32: |
638 if dataSizeIndex >= 0 { | 660 if dataSizeIndex >= 0 { |
639 inst.Prefix[dataSizeIndex] |= PrefixImpl
icit | 661 inst.Prefix[dataSizeIndex] |= PrefixImpl
icit |
640 } | 662 } |
641 pc = int(decoder[pc+1]) | 663 pc = int(decoder[pc+1]) |
642 case 64: | 664 case 64: |
| 665 rexUsed |= PrefixREXW |
643 pc = int(decoder[pc+2]) | 666 pc = int(decoder[pc+2]) |
644 } | 667 } |
645 | 668 |
646 case xCondAddrSize: | 669 case xCondAddrSize: |
647 switch addrMode { | 670 switch addrMode { |
648 case 16: | 671 case 16: |
649 if addrSizeIndex >= 0 { | 672 if addrSizeIndex >= 0 { |
650 inst.Prefix[addrSizeIndex] |= PrefixImpl
icit | 673 inst.Prefix[addrSizeIndex] |= PrefixImpl
icit |
651 } | 674 } |
652 pc = int(decoder[pc]) | 675 pc = int(decoder[pc]) |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 immc = int64(binary.LittleEndian.Uint16(src[pos:])) | 893 immc = int64(binary.LittleEndian.Uint16(src[pos:])) |
871 pos += 2 | 894 pos += 2 |
872 | 895 |
873 case xReadCm: | 896 case xReadCm: |
874 if addrMode == 16 { | 897 if addrMode == 16 { |
875 if pos+2 > len(src) { | 898 if pos+2 > len(src) { |
876 return truncated(src, mode) | 899 return truncated(src, mode) |
877 } | 900 } |
878 immc = int64(binary.LittleEndian.Uint16(src[pos:
])) | 901 immc = int64(binary.LittleEndian.Uint16(src[pos:
])) |
879 pos += 2 | 902 pos += 2 |
880 » » » } else { | 903 » » » } else if addrMode == 32 { |
881 if pos+4 > len(src) { | 904 if pos+4 > len(src) { |
882 return truncated(src, mode) | 905 return truncated(src, mode) |
883 } | 906 } |
884 immc = int64(binary.LittleEndian.Uint32(src[pos:
])) | 907 immc = int64(binary.LittleEndian.Uint32(src[pos:
])) |
885 pos += 4 | 908 pos += 4 |
| 909 } else { |
| 910 if pos+8 > len(src) { |
| 911 return truncated(src, mode) |
| 912 } |
| 913 immc = int64(binary.LittleEndian.Uint64(src[pos:
])) |
| 914 pos += 8 |
886 } | 915 } |
887 case xReadCd: | 916 case xReadCd: |
888 if pos+4 > len(src) { | 917 if pos+4 > len(src) { |
889 return truncated(src, mode) | 918 return truncated(src, mode) |
890 } | 919 } |
891 immc = int64(binary.LittleEndian.Uint32(src[pos:])) | 920 immc = int64(binary.LittleEndian.Uint32(src[pos:])) |
892 pos += 4 | 921 pos += 4 |
893 | 922 |
894 case xReadCp: | 923 case xReadCp: |
895 if pos+6 > len(src) { | 924 if pos+6 > len(src) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 inst.Args[narg+1] = Imm(immc & (1<<16 - 1)) | 1019 inst.Args[narg+1] = Imm(immc & (1<<16 - 1)) |
991 narg += 2 | 1020 narg += 2 |
992 | 1021 |
993 case xArgPtr16colon32: | 1022 case xArgPtr16colon32: |
994 inst.Args[narg] = Imm(immc >> 32) | 1023 inst.Args[narg] = Imm(immc >> 32) |
995 inst.Args[narg+1] = Imm(immc & (1<<32 - 1)) | 1024 inst.Args[narg+1] = Imm(immc & (1<<32 - 1)) |
996 narg += 2 | 1025 narg += 2 |
997 | 1026 |
998 case xArgMoffs8, xArgMoffs16, xArgMoffs32, xArgMoffs64: | 1027 case xArgMoffs8, xArgMoffs16, xArgMoffs32, xArgMoffs64: |
999 // TODO(rsc): Can address be 64 bits? | 1028 // TODO(rsc): Can address be 64 bits? |
1000 » » » mem = Mem{Disp: int32(immc)} | 1029 » » » mem = Mem{Disp: int64(immc)} |
1001 if segIndex >= 0 { | 1030 if segIndex >= 0 { |
1002 mem.Segment = prefixToSegment(inst.Prefix[segInd
ex]) | 1031 mem.Segment = prefixToSegment(inst.Prefix[segInd
ex]) |
1003 inst.Prefix[segIndex] |= PrefixImplicit | 1032 inst.Prefix[segIndex] |= PrefixImplicit |
1004 } | 1033 } |
1005 inst.Args[narg] = mem | 1034 inst.Args[narg] = mem |
1006 inst.MemBytes = int(memBytes[decodeOp(x)]) | 1035 inst.MemBytes = int(memBytes[decodeOp(x)]) |
1007 narg++ | 1036 narg++ |
1008 | 1037 |
1009 » » case xArgR8, xArgR16, xArgR32, xArgR64, xArgXmm, xArgXmm1, xArgM
m, xArgMm1, xArgDR0dashDR7, xArgTR0dashTR7: | 1038 » » case xArgR8, xArgR16, xArgR32, xArgR64, xArgXmm, xArgXmm1, xArgD
R0dashDR7: |
1010 » » » inst.Args[narg] = baseReg[x] + Reg(regop) | 1039 » » » base := baseReg[x] |
| 1040 » » » index := Reg(regop) |
| 1041 » » » if rex != 0 && base == AL && index >= 4 { |
| 1042 » » » » rexUsed |= PrefixREX |
| 1043 » » » » index -= 4 |
| 1044 » » » » base = SPB |
| 1045 » » » } |
| 1046 » » » inst.Args[narg] = base + index |
| 1047 » » » narg++ |
| 1048 |
| 1049 » » case xArgMm, xArgMm1, xArgTR0dashTR7: |
| 1050 » » » inst.Args[narg] = baseReg[x] + Reg(regop&7) |
1011 narg++ | 1051 narg++ |
1012 | 1052 |
1013 case xArgCR0dashCR7: | 1053 case xArgCR0dashCR7: |
1014 // AMD documents an extension that the LOCK prefix | 1054 // AMD documents an extension that the LOCK prefix |
1015 // can be used in place of a REX prefix in order to acce
ss | 1055 // can be used in place of a REX prefix in order to acce
ss |
1016 // CR8 from 32-bit mode. The LOCK prefix is allowed in | 1056 // CR8 from 32-bit mode. The LOCK prefix is allowed in |
1017 // all modes, provided the corresponding CPUID bit is se
t. | 1057 // all modes, provided the corresponding CPUID bit is se
t. |
1018 if lockIndex >= 0 { | 1058 if lockIndex >= 0 { |
1019 inst.Prefix[lockIndex] |= PrefixImplicit | 1059 inst.Prefix[lockIndex] |= PrefixImplicit |
1020 regop += 8 | 1060 regop += 8 |
1021 } | 1061 } |
1022 inst.Args[narg] = CR0 + Reg(regop) | 1062 inst.Args[narg] = CR0 + Reg(regop) |
1023 narg++ | 1063 narg++ |
1024 | 1064 |
1025 case xArgSreg: | 1065 case xArgSreg: |
| 1066 regop &= 7 |
1026 if regop >= 6 { | 1067 if regop >= 6 { |
1027 inst.Op = 0 | 1068 inst.Op = 0 |
1028 break Decode | 1069 break Decode |
1029 } | 1070 } |
1030 inst.Args[narg] = ES + Reg(regop) | 1071 inst.Args[narg] = ES + Reg(regop) |
1031 narg++ | 1072 narg++ |
1032 | 1073 |
1033 case xArgRmf16, xArgRmf32, xArgRmf64: | 1074 case xArgRmf16, xArgRmf32, xArgRmf64: |
1034 » » » inst.Args[narg] = baseReg[x] + Reg(modrm&07) | 1075 » » » base := baseReg[x] |
| 1076 » » » index := Reg(modrm & 07) |
| 1077 » » » if rex&PrefixREXB != 0 { |
| 1078 » » » » rexUsed |= PrefixREXB |
| 1079 » » » » index += 8 |
| 1080 » » » } |
| 1081 » » » inst.Args[narg] = base + index |
1035 narg++ | 1082 narg++ |
1036 | 1083 |
1037 case xArgR8op, xArgR16op, xArgR32op, xArgR64op, xArgSTi: | 1084 case xArgR8op, xArgR16op, xArgR32op, xArgR64op, xArgSTi: |
1038 n := inst.Opcode >> uint(opshift+8) & 07 | 1085 n := inst.Opcode >> uint(opshift+8) & 07 |
1039 » » » inst.Args[narg] = baseReg[x] + Reg(n) | 1086 » » » base := baseReg[x] |
| 1087 » » » index := Reg(n) |
| 1088 » » » if rex&PrefixREXB != 0 && decodeOp(x) != xArgSTi { |
| 1089 » » » » rexUsed |= PrefixREXB |
| 1090 » » » » index += 8 |
| 1091 » » » } |
| 1092 » » » if rex != 0 && base == AL && index >= 4 { |
| 1093 » » » » rexUsed |= PrefixREX |
| 1094 » » » » index -= 4 |
| 1095 » » » » base = SPB |
| 1096 » » » } |
| 1097 » » » inst.Args[narg] = base + index |
1040 narg++ | 1098 narg++ |
1041 | 1099 |
1042 case xArgRM8, xArgRM16, xArgRM32, xArgRM64, xArgR32M16, xArgR32M
8, xArgR64M16, | 1100 case xArgRM8, xArgRM16, xArgRM32, xArgRM64, xArgR32M16, xArgR32M
8, xArgR64M16, |
1043 xArgMmM32, xArgMmM64, xArgMm2M64, | 1101 xArgMmM32, xArgMmM64, xArgMm2M64, |
1044 xArgXmm2M16, xArgXmm2M32, xArgXmm2M64, xArgXmmM64, xArgX
mmM128, xArgXmmM32, xArgXmm2M128: | 1102 xArgXmm2M16, xArgXmm2M32, xArgXmm2M64, xArgXmmM64, xArgX
mmM128, xArgXmmM32, xArgXmm2M128: |
1045 if haveMem { | 1103 if haveMem { |
1046 inst.Args[narg] = mem | 1104 inst.Args[narg] = mem |
1047 inst.MemBytes = int(memBytes[decodeOp(x)]) | 1105 inst.MemBytes = int(memBytes[decodeOp(x)]) |
1048 } else { | 1106 } else { |
1049 » » » » inst.Args[narg] = baseReg[x] + Reg(rm) | 1107 » » » » base := baseReg[x] |
| 1108 » » » » index := Reg(rm) |
| 1109 » » » » switch decodeOp(x) { |
| 1110 » » » » case xArgMmM32, xArgMmM64, xArgMm2M64: |
| 1111 » » » » » // There are only 8 MMX registers, so th
ese ignore the REX.X bit. |
| 1112 » » » » » index &= 7 |
| 1113 » » » » case xArgRM8: |
| 1114 » » » » » if rex != 0 && index >= 4 { |
| 1115 » » » » » » rexUsed |= PrefixREX |
| 1116 » » » » » » index -= 4 |
| 1117 » » » » » » base = SPB |
| 1118 » » » » » } |
| 1119 » » » » } |
| 1120 » » » » inst.Args[narg] = base + index |
1050 } | 1121 } |
1051 narg++ | 1122 narg++ |
1052 | 1123 |
1053 » » case xArgMm2, xArgXmm2: // register only; TODO(rsc): Handle with
tag modrm_regonly tag | 1124 » » case xArgMm2: // register only; TODO(rsc): Handle with tag modrm
_regonly tag |
1054 if haveMem { | 1125 if haveMem { |
1055 inst.Op = 0 | 1126 inst.Op = 0 |
1056 break Decode | 1127 break Decode |
| 1128 } |
| 1129 inst.Args[narg] = baseReg[x] + Reg(rm&7) |
| 1130 narg++ |
| 1131 |
| 1132 case xArgXmm2: // register only; TODO(rsc): Handle with tag modr
m_regonly tag |
| 1133 if haveMem { |
| 1134 inst.Op = 0 |
| 1135 break Decode |
1057 } | 1136 } |
1058 inst.Args[narg] = baseReg[x] + Reg(rm) | 1137 inst.Args[narg] = baseReg[x] + Reg(rm) |
1059 narg++ | 1138 narg++ |
1060 | 1139 |
1061 case xArgRel8: | 1140 case xArgRel8: |
1062 inst.Args[narg] = Rel(int8(immc)) | 1141 inst.Args[narg] = Rel(int8(immc)) |
1063 narg++ | 1142 narg++ |
1064 | 1143 |
1065 case xArgRel16: | 1144 case xArgRel16: |
1066 inst.Args[narg] = Rel(int16(immc)) | 1145 inst.Args[narg] = Rel(int16(immc)) |
1067 narg++ | 1146 narg++ |
1068 | 1147 |
1069 case xArgRel32: | 1148 case xArgRel32: |
1070 inst.Args[narg] = Rel(int32(immc)) | 1149 inst.Args[narg] = Rel(int32(immc)) |
1071 narg++ | 1150 narg++ |
1072 } | 1151 } |
1073 } | 1152 } |
1074 | 1153 |
1075 if inst.Op == 0 { | 1154 if inst.Op == 0 { |
1076 // Invalid instruction. | 1155 // Invalid instruction. |
1077 if nprefix > 0 { | 1156 if nprefix > 0 { |
1078 return instPrefix(src[0], mode) // invalid instruction | 1157 return instPrefix(src[0], mode) // invalid instruction |
1079 } | 1158 } |
1080 return Inst{}, pos, ErrUnrecognized | 1159 return Inst{}, pos, ErrUnrecognized |
1081 } | 1160 } |
1082 | 1161 |
1083 // Matched! Hooray! | 1162 // Matched! Hooray! |
1084 | 1163 |
| 1164 // 90 decodes as XCHG EAX, EAX but is NOP. |
| 1165 // 66 90 decodes as XCHG AX, AX and is NOP too. |
| 1166 // 48 90 decodes as XCHG RAX, RAX and is NOP too. |
| 1167 // 43 90 decodes as XCHG R8D, EAX and is *not* NOP. |
| 1168 // F3 90 decodes as REP XCHG EAX, EAX but is PAUSE. |
| 1169 // It's all too special to handle in the decoding tables, at least for n
ow. |
| 1170 if inst.Op == XCHG && inst.Opcode>>24 == 0x90 { |
| 1171 if inst.Args[0] == RAX || inst.Args[0] == EAX || inst.Args[0] ==
AX { |
| 1172 inst.Op = NOP |
| 1173 if dataSizeIndex >= 0 { |
| 1174 inst.Prefix[dataSizeIndex] &^= PrefixImplicit |
| 1175 } |
| 1176 inst.Args[0] = nil |
| 1177 inst.Args[1] = nil |
| 1178 } |
| 1179 if repIndex >= 0 && inst.Prefix[repIndex] == 0xF3 { |
| 1180 inst.Prefix[repIndex] |= PrefixImplicit |
| 1181 inst.Op = PAUSE |
| 1182 inst.Args[0] = nil |
| 1183 inst.Args[1] = nil |
| 1184 } else if gnuCompat { |
| 1185 for i := nprefix - 1; i >= 0; i-- { |
| 1186 if inst.Prefix[i]&0xFF == 0xF3 { |
| 1187 inst.Prefix[i] |= PrefixImplicit |
| 1188 inst.Op = PAUSE |
| 1189 inst.Args[0] = nil |
| 1190 inst.Args[1] = nil |
| 1191 break |
| 1192 } |
| 1193 } |
| 1194 } |
| 1195 } |
| 1196 |
1085 // defaultSeg returns the default segment for an implicit | 1197 // defaultSeg returns the default segment for an implicit |
1086 // memory reference: the final override if present, or else DS. | 1198 // memory reference: the final override if present, or else DS. |
1087 defaultSeg := func() Reg { | 1199 defaultSeg := func() Reg { |
1088 if segIndex >= 0 { | 1200 if segIndex >= 0 { |
1089 inst.Prefix[segIndex] |= PrefixImplicit | 1201 inst.Prefix[segIndex] |= PrefixImplicit |
1090 return prefixToSegment(inst.Prefix[segIndex]) | 1202 return prefixToSegment(inst.Prefix[segIndex]) |
1091 } | 1203 } |
1092 return DS | 1204 return DS |
1093 } | 1205 } |
1094 | 1206 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 // since segment prefixes don't make sense on conditional jumps. | 1301 // since segment prefixes don't make sense on conditional jumps. |
1190 // Rewrite final instance to prediction prefix. | 1302 // Rewrite final instance to prediction prefix. |
1191 // The set of instructions to which the prefixes apply (other then the | 1303 // The set of instructions to which the prefixes apply (other then the |
1192 // Jcc conditional jumps) is not 100% clear from the manuals, but | 1304 // Jcc conditional jumps) is not 100% clear from the manuals, but |
1193 // the disassemblers seem to agree about the LOOP and JCXZ instructions, | 1305 // the disassemblers seem to agree about the LOOP and JCXZ instructions, |
1194 // so we'll follow along. | 1306 // so we'll follow along. |
1195 // TODO(rsc): Perhaps this instruction class should be derived from the
CSV. | 1307 // TODO(rsc): Perhaps this instruction class should be derived from the
CSV. |
1196 if isCondJmp[inst.Op] || isLoop[inst.Op] || inst.Op == JCXZ || inst.Op =
= JECXZ || inst.Op == JRCXZ { | 1308 if isCondJmp[inst.Op] || isLoop[inst.Op] || inst.Op == JCXZ || inst.Op =
= JECXZ || inst.Op == JRCXZ { |
1197 PredictLoop: | 1309 PredictLoop: |
1198 for i := nprefix - 1; i >= 0; i-- { | 1310 for i := nprefix - 1; i >= 0; i-- { |
1199 » » » switch inst.Prefix[i] & 0xFF { | 1311 » » » p := inst.Prefix[i] |
| 1312 » » » switch p & 0xFF { |
1200 case PrefixCS: | 1313 case PrefixCS: |
1201 inst.Prefix[i] = PrefixPN | 1314 inst.Prefix[i] = PrefixPN |
1202 break PredictLoop | 1315 break PredictLoop |
1203 case PrefixDS: | 1316 case PrefixDS: |
1204 inst.Prefix[i] = PrefixPT | 1317 inst.Prefix[i] = PrefixPT |
1205 break PredictLoop | 1318 break PredictLoop |
1206 } | 1319 } |
1207 } | 1320 } |
1208 } | 1321 } |
1209 | 1322 |
1210 // The BND prefix is part of the Intel Memory Protection Extensions (MPX
). | 1323 // The BND prefix is part of the Intel Memory Protection Extensions (MPX
). |
1211 // A REPN applied to certain control transfers is a BND prefix to bound | 1324 // A REPN applied to certain control transfers is a BND prefix to bound |
1212 // the range of possible destinations. There's surprisingly little docum
entation | 1325 // the range of possible destinations. There's surprisingly little docum
entation |
1213 // about this, so we just do what libopcodes and xed agree on. | 1326 // about this, so we just do what libopcodes and xed agree on. |
1214 // In particular, it's unclear why a REPN applied to LOOP or JCXZ instru
ctions | 1327 // In particular, it's unclear why a REPN applied to LOOP or JCXZ instru
ctions |
1215 // does not turn into a BND. | 1328 // does not turn into a BND. |
1216 // TODO(rsc): Perhaps this instruction class should be derived from the
CSV. | 1329 // TODO(rsc): Perhaps this instruction class should be derived from the
CSV. |
1217 if isCondJmp[inst.Op] || inst.Op == JMP || inst.Op == CALL || inst.Op ==
RET { | 1330 if isCondJmp[inst.Op] || inst.Op == JMP || inst.Op == CALL || inst.Op ==
RET { |
1218 for i := nprefix - 1; i >= 0; i-- { | 1331 for i := nprefix - 1; i >= 0; i-- { |
1219 p := inst.Prefix[i] | 1332 p := inst.Prefix[i] |
1220 if p&^PrefixIgnored == PrefixREPN { | 1333 if p&^PrefixIgnored == PrefixREPN { |
1221 » » » » inst.Prefix[i] = p&PrefixIgnored | PrefixBND | 1334 » » » » inst.Prefix[i] = PrefixBND |
1222 break | 1335 break |
1223 } | 1336 } |
1224 } | 1337 } |
1225 } | 1338 } |
1226 | 1339 |
1227 // The LOCK prefix only applies to certain instructions, and then only | 1340 // The LOCK prefix only applies to certain instructions, and then only |
1228 // to instances of the instruction with a memory destination. | 1341 // to instances of the instruction with a memory destination. |
1229 // Other uses of LOCK are invalid and cause a processor exception, | 1342 // Other uses of LOCK are invalid and cause a processor exception, |
1230 // in contrast to the "just ignore it" spirit applied to all other prefi
xes. | 1343 // in contrast to the "just ignore it" spirit applied to all other prefi
xes. |
1231 // Mark invalid lock prefixes. | 1344 // Mark invalid lock prefixes. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 CMPSB, CMPSW, CMPSD, CMPSQ, | 1409 CMPSB, CMPSW, CMPSD, CMPSQ, |
1297 SCASB, SCASW, SCASD, SCASQ, | 1410 SCASB, SCASW, SCASD, SCASQ, |
1298 STOSB, STOSW, STOSD, STOSQ: | 1411 STOSB, STOSW, STOSD, STOSQ: |
1299 // ok | 1412 // ok |
1300 default: | 1413 default: |
1301 inst.Prefix[repIndex] |= PrefixIgnored | 1414 inst.Prefix[repIndex] |= PrefixIgnored |
1302 } | 1415 } |
1303 } | 1416 } |
1304 } | 1417 } |
1305 | 1418 |
| 1419 // If REX was present, mark implicit if all the 1 bits were consumed. |
| 1420 if rexIndex >= 0 { |
| 1421 if rexUsed != 0 { |
| 1422 rexUsed |= PrefixREX |
| 1423 } |
| 1424 if rex&^rexUsed == 0 { |
| 1425 inst.Prefix[rexIndex] |= PrefixImplicit |
| 1426 } |
| 1427 } |
| 1428 |
1306 inst.DataSize = dataMode | 1429 inst.DataSize = dataMode |
1307 inst.AddrSize = addrMode | 1430 inst.AddrSize = addrMode |
1308 inst.Mode = mode | 1431 inst.Mode = mode |
1309 return inst, pos, nil | 1432 return inst, pos, nil |
1310 } | 1433 } |
1311 | 1434 |
1312 var errInternal = errors.New("internal error") | 1435 var errInternal = errors.New("internal error") |
1313 | 1436 |
1314 // addr16 records the eight 16-bit addressing modes. | 1437 // addr16 records the eight 16-bit addressing modes. |
1315 var addr16 = [8]Mem{ | 1438 var addr16 = [8]Mem{ |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 } | 1607 } |
1485 | 1608 |
1486 // isLoop records the loop operators. | 1609 // isLoop records the loop operators. |
1487 var isLoop = [maxOp + 1]bool{ | 1610 var isLoop = [maxOp + 1]bool{ |
1488 LOOP: true, | 1611 LOOP: true, |
1489 LOOPE: true, | 1612 LOOPE: true, |
1490 LOOPNE: true, | 1613 LOOPNE: true, |
1491 JECXZ: true, | 1614 JECXZ: true, |
1492 JRCXZ: true, | 1615 JRCXZ: true, |
1493 } | 1616 } |
OLD | NEW |