Lines Matching refs:insn

203 static int consumeByte(struct InternalInstruction* insn, uint8_t* byte) {
204 int ret = insn->reader(insn->readerArg, byte, insn->readerCursor);
207 ++(insn->readerCursor);
219 static int lookAtByte(struct InternalInstruction* insn, uint8_t* byte) {
220 return insn->reader(insn->readerArg, byte, insn->readerCursor);
223 static void unconsumeByte(struct InternalInstruction* insn) {
224 insn->readerCursor--;
228 static int name(struct InternalInstruction* insn, type* ptr) { \
233 int ret = insn->reader(insn->readerArg, \
235 insn->readerCursor + offset); \
241 insn->readerCursor += sizeof(type); \
270 static void dbgprintf(struct InternalInstruction* insn,
276 if (!insn->dlog)
283 insn->dlog(insn->dlogArg, buffer);
286 static bool isREX(struct InternalInstruction *insn, uint8_t prefix) {
287 if (insn->mode == MODE_64BIT)
298 static void setPrefixPresent(struct InternalInstruction *insn, uint8_t prefix) {
302 insn->hasLockPrefix = true;
306 if (lookAtByte(insn, &nextByte))
314 if (isREX(insn, nextByte) || nextByte == 0x0f || nextByte == 0x66)
316 insn->mandatoryPrefix = prefix;
317 insn->repeatPrefix = prefix;
320 if (lookAtByte(insn, &nextByte))
323 if (!insn->mandatoryPrefix && (nextByte == 0x0f || isREX(insn, nextByte)))
324 insn->mandatoryPrefix = prefix;
338 static int readPrefixes(struct InternalInstruction* insn) {
343 dbgprintf(insn, "readPrefixes()");
347 if (consumeByte(insn, &byte))
354 if (insn->readerCursor - 1 == insn->startLocation && byte == 0xf0) // LOCK
357 if ((byte == 0xf2 || byte == 0xf3) && !lookAtByte(insn, &nextByte)) {
367 insn->xAcquireRelease = true;
379 insn->xAcquireRelease = true;
383 if (isREX(insn, nextByte)) {
386 if (consumeByte(insn, &nnextByte))
389 if (lookAtByte(insn, &nnextByte))
391 unconsumeByte(insn);
399 setPrefixPresent(insn, byte);
409 insn->segmentOverride = SEG_OVERRIDE_CS;
412 insn->segmentOverride = SEG_OVERRIDE_SS;
415 insn->segmentOverride = SEG_OVERRIDE_DS;
418 insn->segmentOverride = SEG_OVERRIDE_ES;
421 insn->segmentOverride = SEG_OVERRIDE_FS;
424 insn->segmentOverride = SEG_OVERRIDE_GS;
430 setPrefixPresent(insn, byte);
433 insn->hasOpSize = true;
434 setPrefixPresent(insn, byte);
437 insn->hasAdSize = true;
438 setPrefixPresent(insn, byte);
446 dbgprintf(insn, "Found prefix 0x%hhx", byte);
449 insn->vectorExtensionType = TYPE_NO_VEX_XOP;
454 if (consumeByte(insn, &byte1)) {
455 dbgprintf(insn, "Couldn't read second byte of EVEX prefix");
459 if (lookAtByte(insn, &byte2)) {
460 dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
464 if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) &&
466 insn->vectorExtensionType = TYPE_EVEX;
468 unconsumeByte(insn); /* unconsume byte1 */
469 unconsumeByte(insn); /* unconsume byte */
472 if (insn->vectorExtensionType == TYPE_EVEX) {
473 insn->vectorExtensionPrefix[0] = byte;
474 insn->vectorExtensionPrefix[1] = byte1;
475 if (consumeByte(insn, &insn->vectorExtensionPrefix[2])) {
476 dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
479 if (consumeByte(insn, &insn->vectorExtensionPrefix[3])) {
480 dbgprintf(insn, "Couldn't read fourth byte of EVEX prefix");
485 if (insn->mode == MODE_64BIT) {
486 insn->rexPrefix = 0x40
487 | (wFromEVEX3of4(insn->vectorExtensionPrefix[2]) << 3)
488 | (rFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 2)
489 | (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 1)
490 | (bFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 0);
493 dbgprintf(insn, "Found EVEX prefix 0x%hhx 0x%hhx 0x%hhx 0x%hhx",
494 insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
495 insn->vectorExtensionPrefix[2], insn->vectorExtensionPrefix[3]);
500 if (lookAtByte(insn, &byte1)) {
501 dbgprintf(insn, "Couldn't read second byte of VEX");
505 if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)
506 insn->vectorExtensionType = TYPE_VEX_3B;
508 unconsumeByte(insn);
510 if (insn->vectorExtensionType == TYPE_VEX_3B) {
511 insn->vectorExtensionPrefix[0] = byte;
512 consumeByte(insn, &insn->vectorExtensionPrefix[1]);
513 consumeByte(insn, &insn->vectorExtensionPrefix[2]);
517 if (insn->mode == MODE_64BIT)
518 insn->rexPrefix = 0x40
519 | (wFromVEX3of3(insn->vectorExtensionPrefix[2]) << 3)
520 | (rFromVEX2of3(insn->vectorExtensionPrefix[1]) << 2)
521 | (xFromVEX2of3(insn->vectorExtensionPrefix[1]) << 1)
522 | (bFromVEX2of3(insn->vectorExtensionPrefix[1]) << 0);
524 dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx 0x%hhx",
525 insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
526 insn->vectorExtensionPrefix[2]);
531 if (lookAtByte(insn, &byte1)) {
532 dbgprintf(insn, "Couldn't read second byte of VEX");
536 if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)
537 insn->vectorExtensionType = TYPE_VEX_2B;
539 unconsumeByte(insn);
541 if (insn->vectorExtensionType == TYPE_VEX_2B) {
542 insn->vectorExtensionPrefix[0] = byte;
543 consumeByte(insn, &insn->vectorExtensionPrefix[1]);
545 if (insn->mode == MODE_64BIT)
546 insn->rexPrefix = 0x40
547 | (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);
549 switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
553 insn->hasOpSize = true;
557 dbgprintf(insn, "Found VEX prefix 0x%hhx 0x%hhx",
558 insn->vectorExtensionPrefix[0],
559 insn->vectorExtensionPrefix[1]);
564 if (lookAtByte(insn, &byte1)) {
565 dbgprintf(insn, "Couldn't read second byte of XOP");
570 insn->vectorExtensionType = TYPE_XOP;
572 unconsumeByte(insn);
574 if (insn->vectorExtensionType == TYPE_XOP) {
575 insn->vectorExtensionPrefix[0] = byte;
576 consumeByte(insn, &insn->vectorExtensionPrefix[1]);
577 consumeByte(insn, &insn->vectorExtensionPrefix[2]);
581 if (insn->mode == MODE_64BIT)
582 insn->rexPrefix = 0x40
583 | (wFromXOP3of3(insn->vectorExtensionPrefix[2]) << 3)
584 | (rFromXOP2of3(insn->vectorExtensionPrefix[1]) << 2)
585 | (xFromXOP2of3(insn->vectorExtensionPrefix[1]) << 1)
586 | (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);
588 switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
592 insn->hasOpSize = true;
596 dbgprintf(insn, "Found XOP prefix 0x%hhx 0x%hhx 0x%hhx",
597 insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
598 insn->vectorExtensionPrefix[2]);
600 } else if (isREX(insn, byte)) {
601 if (lookAtByte(insn, &nextByte))
603 insn->rexPrefix = byte;
604 dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
606 unconsumeByte(insn);
608 if (insn->mode == MODE_16BIT) {
609 insn->registerSize = (insn->hasOpSize ? 4 : 2);
610 insn->addressSize = (insn->hasAdSize ? 4 : 2);
611 insn->displacementSize = (insn->hasAdSize ? 4 : 2);
612 insn->immediateSize = (insn->hasOpSize ? 4 : 2);
613 } else if (insn->mode == MODE_32BIT) {
614 insn->registerSize = (insn->hasOpSize ? 2 : 4);
615 insn->addressSize = (insn->hasAdSize ? 2 : 4);
616 insn->displacementSize = (insn->hasAdSize ? 2 : 4);
617 insn->immediateSize = (insn->hasOpSize ? 2 : 4);
618 } else if (insn->mode == MODE_64BIT) {
619 if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
620 insn->registerSize = 8;
621 insn->addressSize = (insn->hasAdSize ? 4 : 8);
622 insn->displacementSize = 4;
623 insn->immediateSize = 4;
625 insn->registerSize = (insn->hasOpSize ? 2 : 4);
626 insn->addressSize = (insn->hasAdSize ? 4 : 8);
627 insn->displacementSize = (insn->hasOpSize ? 2 : 4);
628 insn->immediateSize = (insn->hasOpSize ? 2 : 4);
635 static int readModRM(struct InternalInstruction* insn);
644 static int readOpcode(struct InternalInstruction* insn) {
649 dbgprintf(insn, "readOpcode()");
651 insn->opcodeType = ONEBYTE;
653 if (insn->vectorExtensionType == TYPE_EVEX) {
654 switch (mmFromEVEX2of4(insn->vectorExtensionPrefix[1])) {
656 dbgprintf(insn, "Unhandled mm field for instruction (0x%hhx)",
657 mmFromEVEX2of4(insn->vectorExtensionPrefix[1]));
660 insn->opcodeType = TWOBYTE;
661 return consumeByte(insn, &insn->opcode);
663 insn->opcodeType = THREEBYTE_38;
664 return consumeByte(insn, &insn->opcode);
666 insn->opcodeType = THREEBYTE_3A;
667 return consumeByte(insn, &insn->opcode);
669 } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
670 switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
672 dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
673 mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
676 insn->opcodeType = TWOBYTE;
677 return consumeByte(insn, &insn->opcode);
679 insn->opcodeType = THREEBYTE_38;
680 return consumeByte(insn, &insn->opcode);
682 insn->opcodeType = THREEBYTE_3A;
683 return consumeByte(insn, &insn->opcode);
685 } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
686 insn->opcodeType = TWOBYTE;
687 return consumeByte(insn, &insn->opcode);
688 } else if (insn->vectorExtensionType == TYPE_XOP) {
689 switch (mmmmmFromXOP2of3(insn->vectorExtensionPrefix[1])) {
691 dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
692 mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
695 insn->opcodeType = XOP8_MAP;
696 return consumeByte(insn, &insn->opcode);
698 insn->opcodeType = XOP9_MAP;
699 return consumeByte(insn, &insn->opcode);
701 insn->opcodeType = XOPA_MAP;
702 return consumeByte(insn, &insn->opcode);
706 if (consumeByte(insn, &current))
710 dbgprintf(insn, "Found a two-byte escape prefix (0x%hhx)", current);
712 if (consumeByte(insn, &current))
716 dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
718 if (consumeByte(insn, &current))
721 insn->opcodeType = THREEBYTE_38;
723 dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
725 if (consumeByte(insn, &current))
728 insn->opcodeType = THREEBYTE_3A;
730 dbgprintf(insn, "Found a 3dnow escape prefix (0x%hhx)", current);
733 if (readModRM(insn))
736 if (consumeByte(insn, &current))
739 insn->opcodeType = THREEDNOW_MAP;
741 dbgprintf(insn, "Didn't find a three-byte escape prefix");
743 insn->opcodeType = TWOBYTE;
745 } else if (insn->mandatoryPrefix)
748 insn->mandatoryPrefix = 0;
755 insn->opcode = current;
773 struct InternalInstruction* insn,
779 hasModRMExtension = modRMRequired(insn->opcodeType,
781 insn->opcode);
784 if (readModRM(insn))
787 *instructionID = decode(insn->opcodeType,
789 insn->opcode,
790 insn->modRM);
792 *instructionID = decode(insn->opcodeType,
794 insn->opcode,
853 static int getID(struct InternalInstruction* insn, const void *miiArg) {
857 dbgprintf(insn, "getID()");
861 if (insn->mode == MODE_64BIT)
864 if (insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
865 attrMask |= (insn->vectorExtensionType == TYPE_EVEX) ? ATTR_EVEX : ATTR_VEX;
867 if (insn->vectorExtensionType == TYPE_EVEX) {
868 switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
880 if (zFromEVEX4of4(insn->vectorExtensionPrefix[3]))
882 if (bFromEVEX4of4(insn->vectorExtensionPrefix[3]))
884 if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]))
886 if (lFromEVEX4of4(insn->vectorExtensionPrefix[3]))
888 if (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
890 } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
891 switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
903 if (lFromVEX3of3(insn->vectorExtensionPrefix[2]))
905 } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
906 switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
918 if (lFromVEX2of2(insn->vectorExtensionPrefix[1]))
920 } else if (insn->vectorExtensionType == TYPE_XOP) {
921 switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
933 if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
938 } else if (!insn->mandatoryPrefix) {
940 if (insn->hasOpSize && (insn->mode != MODE_16BIT))
942 if (insn->hasAdSize)
944 if (insn->opcodeType == ONEBYTE) {
945 if (insn->repeatPrefix == 0xf3 && (insn->opcode == 0x90))
949 if (insn->repeatPrefix == 0xf2)
951 else if (insn->repeatPrefix == 0xf3)
955 switch (insn->mandatoryPrefix) {
963 if (insn->mode != MODE_16BIT)
973 if (insn->rexPrefix & 0x08) {
982 if (insn->mode == MODE_16BIT && insn->opcodeType == ONEBYTE &&
983 insn->opcode == 0xE3)
991 if ((insn->mode == MODE_64BIT) && insn->hasOpSize) {
992 switch (insn->opcode) {
996 if (insn->opcodeType == ONEBYTE) {
998 insn->immediateSize = 4;
999 insn->displacementSize = 4;
1017 if (insn->opcodeType == TWOBYTE) {
1019 insn->immediateSize = 4;
1020 insn->displacementSize = 4;
1026 if (getIDWithAttrMask(&instructionID, insn, attrMask))
1031 if (insn->mode != MODE_64BIT &&
1032 insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
1037 if ((insn->vectorExtensionType == TYPE_EVEX &&
1038 wFromEVEX3of4(insn->vectorExtensionPrefix[2])) ||
1039 (insn->vectorExtensionType == TYPE_VEX_3B &&
1040 wFromVEX3of3(insn->vectorExtensionPrefix[2])) ||
1041 (insn->vectorExtensionType == TYPE_XOP &&
1042 wFromXOP3of3(insn->vectorExtensionPrefix[2]))) {
1046 insn, attrMask | ATTR_REXW)) {
1047 insn->instructionID = instructionID;
1048 insn->spec = specifierForUID(instructionID);
1055 insn->instructionID = instructionIDWithREXW;
1056 insn->spec = specifierForUID(instructionIDWithREXW);
1069 if ((insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) ||
1070 (insn->opcodeType == TWOBYTE && (insn->opcode == 0xAE)) ||
1071 (insn->opcodeType == THREEBYTE_38 && insn->opcode == 0xF8)) {
1073 if (insn->hasAdSize)
1075 if (insn->hasOpSize)
1079 if (insn->mode == MODE_16BIT) {
1083 if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0))
1087 if (getIDWithAttrMask(&instructionID, insn, attrMask))
1090 insn->instructionID = instructionID;
1091 insn->spec = specifierForUID(instructionID);
1095 if ((insn->mode == MODE_16BIT || insn->hasOpSize) &&
1112 insn,
1119 insn->instructionID = instructionID;
1120 insn->spec = spec;
1128 (insn->mode == MODE_16BIT) ^ insn->hasOpSize) {
1129 insn->instructionID = instructionIDWithOpsize;
1130 insn->spec = specifierForUID(instructionIDWithOpsize);
1132 insn->instructionID = instructionID;
1133 insn->spec = spec;
1138 if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 &&
1139 insn->rexPrefix & 0x01) {
1152 insn->opcode = 0x91;
1155 insn,
1157 insn->opcode = 0x90;
1159 insn->instructionID = instructionID;
1160 insn->spec = spec;
1167 insn->opcode = 0x90;
1169 insn->instructionID = instructionIDWithNewOpcode;
1170 insn->spec = specWithNewOpcode;
1175 insn->instructionID = instructionID;
1176 insn->spec = specifierForUID(insn->instructionID);
1188 static int readSIB(struct InternalInstruction* insn) {
1192 dbgprintf(insn, "readSIB()");
1194 if (insn->consumedSIB)
1197 insn->consumedSIB = true;
1199 switch (insn->addressSize) {
1201 dbgprintf(insn, "SIB-based addressing doesn't work in 16-bit mode");
1204 insn->sibIndexBase = SIB_INDEX_EAX;
1208 insn->sibIndexBase = SIB_INDEX_RAX;
1213 if (consumeByte(insn, &insn->sib))
1216 index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3);
1219 insn->sibIndex = SIB_INDEX_NONE;
1221 insn->sibIndex = (SIBIndex)(insn->sibIndexBase + index);
1224 insn->sibScale = 1 << scaleFromSIB(insn->sib);
1226 base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);
1231 switch (modFromModRM(insn->modRM)) {
1233 insn->eaDisplacement = EA_DISP_32;
1234 insn->sibBase = SIB_BASE_NONE;
1237 insn->eaDisplacement = EA_DISP_8;
1238 insn->sibBase = (SIBBase)(sibBaseBase + base);
1241 insn->eaDisplacement = EA_DISP_32;
1242 insn->sibBase = (SIBBase)(sibBaseBase + base);
1250 insn->sibBase = (SIBBase)(sibBaseBase + base);
1264 static int readDisplacement(struct InternalInstruction* insn) {
1269 dbgprintf(insn, "readDisplacement()");
1271 if (insn->consumedDisplacement)
1274 insn->consumedDisplacement = true;
1275 insn->displacementOffset = insn->readerCursor - insn->startLocation;
1277 switch (insn->eaDisplacement) {
1279 insn->consumedDisplacement = false;
1282 if (consumeInt8(insn, &d8))
1284 insn->displacement = d8;
1287 if (consumeInt16(insn, &d16))
1289 insn->displacement = d16;
1292 if (consumeInt32(insn, &d32))
1294 insn->displacement = d32;
1298 insn->consumedDisplacement = true;
1309 static int readModRM(struct InternalInstruction* insn) {
1312 dbgprintf(insn, "readModRM()");
1314 if (insn->consumedModRM)
1317 if (consumeByte(insn, &insn->modRM))
1319 insn->consumedModRM = true;
1321 mod = modFromModRM(insn->modRM);
1322 rm = rmFromModRM(insn->modRM);
1323 reg = regFromModRM(insn->modRM);
1330 switch (insn->registerSize) {
1332 insn->regBase = MODRM_REG_AX;
1333 insn->eaRegBase = EA_REG_AX;
1336 insn->regBase = MODRM_REG_EAX;
1337 insn->eaRegBase = EA_REG_EAX;
1340 insn->regBase = MODRM_REG_RAX;
1341 insn->eaRegBase = EA_REG_RAX;
1345 reg |= rFromREX(insn->rexPrefix) << 3;
1346 rm |= bFromREX(insn->rexPrefix) << 3;
1349 if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT) {
1350 reg |= r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
1351 evexrm = xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
1354 insn->reg = (Reg)(insn->regBase + reg);
1356 switch (insn->addressSize) {
1363 insn->eaBase = EA_BASE_NONE;
1364 insn->eaDisplacement = EA_DISP_16;
1365 if (readDisplacement(insn))
1368 insn->eaBase = (EABase)(eaBaseBase + rm);
1369 insn->eaDisplacement = EA_DISP_NONE;
1373 insn->eaBase = (EABase)(eaBaseBase + rm);
1374 insn->eaDisplacement = EA_DISP_8;
1375 insn->displacementSize = 1;
1376 if (readDisplacement(insn))
1380 insn->eaBase = (EABase)(eaBaseBase + rm);
1381 insn->eaDisplacement = EA_DISP_16;
1382 if (readDisplacement(insn))
1386 insn->eaBase = (EABase)(insn->eaRegBase + rm);
1387 if (readDisplacement(insn))
1395 EABase eaBaseBase = (insn->addressSize == 4 ? EA_BASE_EAX : EA_BASE_RAX);
1399 insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */
1405 insn->eaBase = (insn->addressSize == 4 ?
1407 if (readSIB(insn) || readDisplacement(insn))
1411 insn->eaBase = EA_BASE_NONE;
1412 insn->eaDisplacement = EA_DISP_32;
1413 if (readDisplacement(insn))
1417 insn->eaBase = (EABase)(eaBaseBase + rm);
1422 insn->displacementSize = 1;
1425 insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
1428 insn->eaBase = EA_BASE_sib;
1429 if (readSIB(insn) || readDisplacement(insn))
1433 insn->eaBase = (EABase)(eaBaseBase + rm);
1434 if (readDisplacement(insn))
1440 insn->eaDisplacement = EA_DISP_NONE;
1441 insn->eaBase = (EABase)(insn->eaRegBase + rm + evexrm);
1452 static uint16_t name(struct InternalInstruction *insn, \
1468 if (insn->rexPrefix && \
1536 GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase, MODRM_REG, 0x1f)
1537 GENERIC_FIXUP_FUNC(fixupRMValue, insn->eaRegBase, EA_REG, 0xf)
1548 static int fixupReg(struct InternalInstruction *insn,
1552 dbgprintf(insn, "fixupReg()");
1559 insn->vvvv = (Reg)fixupRegValue(insn,
1561 insn->vvvv,
1567 insn->reg = (Reg)fixupRegValue(insn,
1569 insn->reg - insn->regBase,
1575 if (insn->eaBase >= insn->eaRegBase) {
1576 insn->eaBase = (EABase)fixupRMValue(insn,
1578 insn->eaBase - insn->eaRegBase,
1600 static int readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
1601 dbgprintf(insn, "readOpcodeRegister()");
1604 size = insn->registerSize;
1608 insn->opcodeRegister = (Reg)(MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3)
1609 | (insn->opcode & 7)));
1610 if (insn->rexPrefix &&
1611 insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
1612 insn->opcodeRegister < MODRM_REG_AL + 0x8) {
1613 insn->opcodeRegister = (Reg)(MODRM_REG_SPL
1614 + (insn->opcodeRegister - MODRM_REG_AL - 4));
1619 insn->opcodeRegister = (Reg)(MODRM_REG_AX
1620 + ((bFromREX(insn->rexPrefix) << 3)
1621 | (insn->opcode & 7)));
1624 insn->opcodeRegister = (Reg)(MODRM_REG_EAX
1625 + ((bFromREX(insn->rexPrefix) << 3)
1626 | (insn->opcode & 7)));
1629 insn->opcodeRegister = (Reg)(MODRM_REG_RAX
1630 + ((bFromREX(insn->rexPrefix) << 3)
1631 | (insn->opcode & 7)));
1647 static int readImmediate(struct InternalInstruction* insn, uint8_t size) {
1653 dbgprintf(insn, "readImmediate()");
1655 if (insn->numImmediatesConsumed == 2) {
1661 size = insn->immediateSize;
1663 insn->immediateSize = size;
1664 insn->immediateOffset = insn->readerCursor - insn->startLocation;
1668 if (consumeByte(insn, &imm8))
1670 insn->immediates[insn->numImmediatesConsumed] = imm8;
1673 if (consumeUInt16(insn, &imm16))
1675 insn->immediates[insn->numImmediatesConsumed] = imm16;
1678 if (consumeUInt32(insn, &imm32))
1680 insn->immediates[insn->numImmediatesConsumed] = imm32;
1683 if (consumeUInt64(insn, &imm64))
1685 insn->immediates[insn->numImmediatesConsumed] = imm64;
1689 insn->numImmediatesConsumed++;
1701 static int readVVVV(struct InternalInstruction* insn) {
1702 dbgprintf(insn, "readVVVV()");
1705 if (insn->vectorExtensionType == TYPE_EVEX)
1706 vvvv = (v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4 |
1707 vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]));
1708 else if (insn->vectorExtensionType == TYPE_VEX_3B)
1709 vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]);
1710 else if (insn->vectorExtensionType == TYPE_VEX_2B)
1711 vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]);
1712 else if (insn->vectorExtensionType == TYPE_XOP)
1713 vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]);
1717 if (insn->mode != MODE_64BIT)
1720 insn->vvvv = static_cast<Reg>(vvvv);
1731 static int readMaskRegister(struct InternalInstruction* insn) {
1732 dbgprintf(insn, "readMaskRegister()");
1734 if (insn->vectorExtensionType != TYPE_EVEX)
1737 insn->writemask =
1738 static_cast<Reg>(aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]));
1749 static int readOperands(struct InternalInstruction* insn) {
1753 dbgprintf(insn, "readOperands()");
1757 hasVVVV = !readVVVV(insn);
1758 needVVVV = hasVVVV && (insn->vvvv != 0);
1760 for (const auto &Op : x86OperandSets[insn->spec->operands]) {
1769 needVVVV = hasVVVV & ((insn->vvvv & 0xf) != 0);
1770 if (readModRM(insn))
1774 if (insn->eaBase != EA_BASE_sib && insn->eaBase != EA_BASE_sib64)
1778 if (insn->sibIndex == SIB_INDEX_NONE)
1779 insn->sibIndex = (SIBIndex)(insn->sibIndexBase + 4);
1782 if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT &&
1783 v2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
1784 insn->sibIndex = (SIBIndex)(insn->sibIndex + 16);
1792 insn->sibIndex = (SIBIndex)(SIB_INDEX_XMM0 +
1793 (insn->sibIndex - insn->sibIndexBase));
1796 insn->sibIndex = (SIBIndex)(SIB_INDEX_YMM0 +
1797 (insn->sibIndex - insn->sibIndexBase));
1800 insn->sibIndex = (SIBIndex)(SIB_INDEX_ZMM0 +
1801 (insn->sibIndex - insn->sibIndexBase));
1806 if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
1807 insn->displacement *= 1 << (Op.encoding - ENCODING_VSIB);
1811 if (readModRM(insn))
1813 if (fixupReg(insn, &Op))
1816 if (Op.encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
1817 insn->displacement *= 1 << (Op.encoding - ENCODING_RM);
1823 insn->immediates[insn->numImmediatesConsumed] =
1824 insn->immediates[insn->numImmediatesConsumed - 1] & 0xf;
1825 ++insn->numImmediatesConsumed;
1828 if (readImmediate(insn, 1))
1834 if (readImmediate(insn, 2))
1838 if (readImmediate(insn, 4))
1842 if (readImmediate(insn, 8))
1846 if (readImmediate(insn, insn->immediateSize))
1850 if (readImmediate(insn, insn->addressSize))
1854 insn->RC = (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 1) |
1855 lFromEVEX4of4(insn->vectorExtensionPrefix[3]);
1858 if (readOpcodeRegister(insn, 1))
1862 if (readOpcodeRegister(insn, 2))
1866 if (readOpcodeRegister(insn, 4))
1870 if (readOpcodeRegister(insn, 8))
1874 if (readOpcodeRegister(insn, 0))
1883 if (insn->mode != MODE_64BIT)
1884 insn->vvvv = static_cast<Reg>(insn->vvvv & 0x7);
1885 if (fixupReg(insn, &Op))
1889 if (readMaskRegister(insn))
1895 dbgprintf(insn, "Encountered an operand with an unknown encoding.");
1927 struct InternalInstruction *insn, byteReader_t reader,
1930 memset(insn, 0, sizeof(struct InternalInstruction));
1932 insn->reader = reader;
1933 insn->readerArg = readerArg;
1934 insn->dlog = logger;
1935 insn->dlogArg = loggerArg;
1936 insn->startLocation = startLoc;
1937 insn->readerCursor = startLoc;
1938 insn->mode = mode;
1939 insn->numImmediatesConsumed = 0;
1941 if (readPrefixes(insn) ||
1942 readOpcode(insn) ||
1943 getID(insn, miiArg) ||
1944 insn->instructionID == 0 ||
1945 readOperands(insn))
1948 insn->operands = x86OperandSets[insn->spec->operands];
1950 insn->length = insn->readerCursor - insn->startLocation;
1952 dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %zu",
1953 startLoc, insn->readerCursor, insn->length);
1955 if (insn->length > 15)
1956 dbgprintf(insn, "Instruction exceeds 15-byte limit");