MODULE AMD64Decoder;
IMPORT SYSTEM, Decoder, Streams;
CONST
objFileSuffix = "Abx";
maxArgs = 3;
prOperand = 0;
prAddress = 1;
prCS = 2;
prDS = 3;
prES = 4;
prFS = 5;
prGS = 6;
prSS = 7;
prLOCK = 8;
prREP = 9;
prREPN = 10;
prF3 = prREP;
pr66 = prOperand;
prF2 = prREPN;
prREX = 11;
prREXW = 12;
prREXR = 13;
prREXX = 14;
prREXB = 15;
opInvalid = 0;
opReserved = 1;
opADC = 2;
opADD = 3;
opADDPD = 4;
opADDPS = 5;
opADDSD = 6;
opADDSS = 7;
opADDSUBPD = 8;
opADDSUBPS = 9;
opAND = 10;
opANDNPD = 11;
opANDNPS = 12;
opANDPD = 13;
opANDPS = 14;
opBSF = 15;
opBSR = 16;
opBSWAP = 17;
opBT = 18;
opBTC = 19;
opBTR = 20;
opBTS = 21;
opCALL = 22;
opCBW = 23;
opCDQ = 24;
opCDQE = 25;
opCLC = 26;
opCLD = 27;
opCLGI = 28;
opCLI = 29;
opCLTS = 30;
opCMC = 31;
opCMP = 32;
opCMPPD = 33;
opCMPPS = 34;
opCMPSB = 35;
opCMPSD = 36;
opCMPSQ = 37;
opCMPSS = 38;
opCMPSW = 39;
opCMPXCHG = 40;
opCMPXCHG16B = 41;
opCMPXCHG8B = 42;
opCOMISD = 43;
opCOMISS = 44;
opCPUID = 45;
opCQO = 46;
opCVTDQ2PD = 47;
opCVTDQ2PS = 48;
opCVTPD2PI = 49;
opCVTPD2PS = 50;
opCVTPI2PD = 51;
opCVTPI2PS = 52;
opCVTPS2DQ = 53;
opCVTPS2PD = 54;
opCVTPS2PI = 55;
opCVTSD2SI = 56;
opCVTSD2SS = 57;
opCVTSI2SD = 58;
opCVTSI2SS = 59;
opCVTSS2SD = 60;
opCVTSS2SI = 61;
opCVTTPD2DQ = 62;
opCVTTPD2PI = 63;
opCVTTPS2DQ = 64;
opCVTTPS2PI = 65;
opCVTTSD2SI = 66;
opCVTTSS2SI = 67;
opCWD = 68;
opCWDE = 69;
opDEC = 70;
opDIV = 71;
opDIVPD = 72;
opDIVPS = 73;
opDIVSD = 74;
opDIVSS = 75;
opEMMS = 76;
opENTER = 77;
opF2XM1 = 78;
opFABS = 79;
opFADD = 80;
opFADDP = 81;
opFBLD = 82;
opFBSTP = 83;
opFCHS = 84;
opFCMOVB = 85;
opFCMOVBE = 86;
opFCMOVE = 87;
opFCMOVNB = 88;
opFCMOVNBE = 89;
opFCMOVNE = 90;
opFCMOVNU = 91;
opFCMOVU = 92;
opFCOM = 93;
opFCOMI = 94;
opFCOMIP = 95;
opFCOMP = 96;
opFCOMPP = 97;
opFCOS = 98;
opFDECSTP = 99;
opFDIV = 100;
opFDIVP = 101;
opFDIVR = 102;
opFDIVRP = 103;
opFEMMS = 104;
opFFREE = 105;
opFIADD = 106;
opFICOM = 107;
opFICOMP = 108;
opFIDIV = 109;
opFIDIVR = 110;
opFILD = 111;
opFIMUL = 112;
opFINCSTP = 113;
opFIST = 114;
opFISTP = 115;
opFISTTP = 116;
opFISUB = 117;
opFISUBR = 118;
opFLD = 119;
opFLD1 = 120;
opFLDCW = 121;
opFLDENV = 122;
opFLDL2E = 123;
opFLDL2T = 124;
opFLDLG2 = 125;
opFLDLN2 = 126;
opFLDPI = 127;
opFLDZ = 128;
opFMUL = 129;
opFMULP = 130;
opFNCLEX = 131;
opFNINIT = 132;
opFNOP = 133;
opFNSAVE = 134;
opFNSTCW = 135;
opFNSTENV = 136;
opFNSTSW = 137;
opFPATAN = 138;
opFPREM = 139;
opFPREM1 = 140;
opFPTAN = 141;
opFRNDINT = 142;
opFRSTOR = 143;
opFSCALE = 144;
opFSIN = 145;
opFSINCOS = 146;
opFSQRT = 147;
opFST = 148;
opFSTP = 149;
opFSUB = 150;
opFSUBP = 151;
opFSUBR = 152;
opFSUBRP = 153;
opFTST = 154;
opFUCOM = 155;
opFUCOMI = 156;
opFUCOMIP = 157;
opFUCOMP = 158;
opFUCOMPP = 159;
opFWAIT = 160;
opFXAM = 161;
opFXCH = 162;
opFXRSTOR = 163;
opFXSAVE = 164;
opFXTRACT = 165;
opFYL2X = 166;
opFYL2XP1 = 167;
opHADDPD = 168;
opHADDPS = 169;
opHLT = 170;
opHSUBPD = 171;
opHSUBPS = 172;
opIDIV = 173;
opIMUL = 174;
opIN = 175;
opINC = 176;
opINSB = 177;
opINSD = 178;
opINSW = 179;
opINT = 180;
opINVD = 181;
opINVLPG = 182;
opINVLPGA = 183;
opIRET = 184;
opIRETD = 185;
opIRETQ = 186;
opJA = 187;
opJB = 188;
opJBE = 189;
opJCXZ = 190;
opJE = 191;
opJECXZ = 192;
opJG = 193;
opJGE = 194;
opJL = 195;
opJLE = 196;
opJMP = 197;
opJNB = 198;
opJNBE = 199;
opJNE = 200;
opJNO = 201;
opJNP = 202;
opJO = 203;
opJP = 204;
opJRCXZ = 205;
opJS = 206;
opLAHF = 207;
opLAR = 208;
opLDDQU = 209;
opLDMXCSR = 210;
opLEA = 211;
opLEAVE = 212;
opLFENCE = 213;
opLFS = 214;
opLGDT = 215;
opLGS = 216;
opLIDT = 217;
opLLDT = 218;
opLMSW = 219;
opLODSB = 220;
opLODSD = 221;
opLODSQ = 222;
opLODSW = 223;
opLOOP = 224;
opLOOPE = 225;
opLOOPNE = 226;
opLSL = 227;
opLSS = 228;
opLTR = 229;
opMASKMOVDQU = 230;
opMASKMOVQ = 231;
opMAXPD = 232;
opMAXPS = 233;
opMAXSD = 234;
opMAXSS = 235;
opMFENCE = 236;
opMINPD = 237;
opMINPS = 238;
opMINSD = 239;
opMINSS = 240;
opMOV = 241;
opMOVA = 242;
opMOVAPD = 243;
opMOVAPS = 244;
opMOVB = 245;
opMOVBE = 246;
opMOVD = 247;
opMOVDDUP = 248;
opMOVDQ2Q = 249;
opMOVDQA = 250;
opMOVDQU = 251;
opMOVE = 252;
opMOVG = 253;
opMOVGE = 254;
opMOVHLPS = 255;
opMOVHPD = 256;
opMOVHPS = 257;
opMOVL = 258;
opMOVLE = 259;
opMOVLHPS = 260;
opMOVLPD = 261;
opMOVLPS = 262;
opMOVMSKPD = 263;
opMOVMSKPS = 264;
opMOVNB = 265;
opMOVNBE = 266;
opMOVNE = 267;
opMOVNO = 268;
opMOVNP = 269;
opMOVNTDQ = 270;
opMOVNTI = 271;
opMOVNTPD = 272;
opMOVNTPS = 273;
opMOVNTQ = 274;
opMOVO = 275;
opMOVP = 276;
opMOVQ = 277;
opMOVQ2DQ = 278;
opMOVS = 279;
opMOVSB = 280;
opMOVSD = 281;
opMOVSHDUP = 282;
opMOVSLDUP = 283;
opMOVSQ = 284;
opMOVSS = 285;
opMOVSW = 286;
opMOVSX = 287;
opMOVSXD = 288;
opMOVUPD = 289;
opMOVUPS = 290;
opMOVZX = 291;
opMUL = 292;
opMULPD = 293;
opMULPS = 294;
opMULSD = 295;
opMULSS = 296;
opNEG = 297;
opNOP = 298;
opNOT = 299;
opOR = 300;
opORPD = 301;
opORPS = 302;
opOUT = 303;
opOUTSB = 304;
opOUTSD = 305;
opOUTSW = 306;
opPACKSSDW = 307;
opPACKSSWB = 308;
opPACKUSWB = 309;
opPADDB = 310;
opPADDD = 311;
opPADDQ = 312;
opPADDSB = 313;
opPADDSW = 314;
opPADDUSB = 315;
opPADDUSW = 316;
opPADDW = 317;
opPAND = 318;
opPANDN = 319;
opPAUSE = 320;
opPAVGB = 321;
opPAVGUSB = 322;
opPAVGW = 323;
opPCMPEQB = 324;
opPCMPEQD = 325;
opPCMPEQW = 326;
opPCMPGTB = 327;
opPCMPGTD = 328;
opPCMPGTW = 329;
opPEXTRW = 330;
opPF2ID = 331;
opPF2IW = 332;
opPFACC = 333;
opPFADD = 334;
opPFCMPEQ = 335;
opPFCMPGE = 336;
opPFCMPGT = 337;
opPFMAX = 338;
opPFMIN = 339;
opPFMUL = 340;
opPFNACC = 341;
opPFPNACC = 342;
opPFRCP = 343;
opPFRCPIT1 = 344;
opPFRSQIT1 = 345;
opPFRSQRT = 346;
opPFSUB = 347;
opPFSUBR = 348;
opPI2FD = 349;
opPI2FW = 350;
opPINSRW = 351;
opPMADDWD = 352;
opPMAXSW = 353;
opPMAXUB = 354;
opPMINSW = 355;
opPMINUB = 356;
opPMOVMSKB = 357;
opPMULHRW = 358;
opPMULHUW = 359;
opPMULHW = 360;
opPMULLW = 361;
opPMULUDQ = 362;
opPOP = 363;
opPOPF = 364;
opPOPFD = 365;
opPOPFQ = 366;
opPOR = 367;
opPREFETCH = 368;
opPREFETCHNTA = 369;
opPREFETCHT0 = 370;
opPREFETCHT1 = 371;
opPREFETCHT2 = 372;
opPREFETCHW = 373;
opPSADBW = 374;
opPSHUFD = 375;
opPSHUFHW = 376;
opPSHUFLW = 377;
opPSHUFW = 378;
opPSLLD = 379;
opPSLLDQ = 380;
opPSLLQ = 381;
opPSLLW = 382;
opPSRAD = 383;
opPSRAW = 384;
opPSRLD = 385;
opPSRLDQ = 386;
opPSRLQ = 387;
opPSRLW = 388;
opPSUBB = 389;
opPSUBD = 390;
opPSUBQ = 391;
opPSUBSB = 392;
opPSUBSW = 393;
opPSUBUSB = 394;
opPSUBUSW = 395;
opPSUBW = 396;
opPSWAPD = 397;
opPUNPCKHBW = 398;
opPUNPCKHDQ = 399;
opPUNPCKHQDQ = 400;
opPUNPCKHWD = 401;
opPUNPCKLBW = 402;
opPUNPCKLDQ = 403;
opPUNPCKLQDQ = 404;
opPUNPCKLWD = 405;
opPUSH = 406;
opPUSHF = 407;
opPUSHFD = 408;
opPUSHFQ = 409;
opPXOR = 410;
opRCL = 411;
opRCPPS = 412;
opRCPSS = 413;
opRCR = 414;
opRDMSR = 415;
opRDPMC = 416;
opRDTSC = 417;
opRDTSCP = 418;
opRET = 419;
opROL = 420;
opROR = 421;
opRSM = 422;
opRSQRTPS = 423;
opRSQRTSS = 424;
opSAHF = 425;
opSAR = 426;
opSBB = 427;
opSCASB = 428;
opSCASD = 429;
opSCASQ = 430;
opSCASW = 431;
opSETA = 432;
opSETB = 433;
opSETBE = 434;
opSETE = 435;
opSETG = 436;
opSETGE = 437;
opSETL = 438;
opSETLE = 439;
opSETNB = 440;
opSETNBE = 441;
opSETNE = 442;
opSETNO = 443;
opSETNP = 444;
opSETO = 445;
opSETP = 446;
opSETS = 447;
opSFENCE = 448;
opSGDT = 449;
opSHL = 450;
opSHLD = 451;
opSHR = 452;
opSHRD = 453;
opSHUFPD = 454;
opSHUFPS = 455;
opSIDT = 456;
opSKINIT = 457;
opSLDT = 458;
opSMSW = 459;
opSQRTPD = 460;
opSQRTPS = 461;
opSQRTSD = 462;
opSQRTSS = 463;
opSTC = 464;
opSTD = 465;
opSTGI = 466;
opSTI = 467;
opSTMXCSR = 468;
opSTOSB = 469;
opSTOSD = 470;
opSTOSQ = 471;
opSTOSW = 472;
opSTR = 473;
opSUB = 474;
opSUBPD = 475;
opSUBPS = 476;
opSUBSD = 477;
opSUBSS = 478;
opSWAPGS = 479;
opSYSCALL = 480;
opSYSRET = 481;
opTEST = 482;
opUCOMISD = 483;
opUCOMISS = 484;
opUD2 = 485;
opUNPCKHPD = 486;
opUNPCKHPS = 487;
opUNPCKLPD = 488;
opUNPCKLPS = 489;
opVERR = 490;
opVERW = 491;
opVMLOAD = 492;
opVMMCALL = 493;
opVMRUN = 494;
opVMSAVE = 495;
opWBINVD = 496;
opWRMSR = 497;
opXADD = 498;
opXCHG = 499;
opXLAT = 500;
opXOR = 501;
opXORPD = 502;
opXORPS = 503;
regNONE = 0;
regrAX = 0;
regrCX = 1;
regrDX = 2;
regrBX = 3;
regrSP = 4;
regrBP = 5;
regrSI = 6;
regrDI = 7;
regr8 = 8;
regr9 = 9;
regr10 = 10;
regr11 = 11;
regr12 = 12;
regr13 = 13;
regr14 = 14;
regr15 = 15;
regAL = 1;
regCL = 2;
regDL = 3;
regBL = 4;
regAH = 5;
regCH = 6;
regDH = 7;
regBH = 8;
regR8B = 9;
regR9B = 10;
regR10B = 11;
regR11B = 12;
regR12B = 13;
regR13B = 14;
regR14B = 15;
regR15B = 16;
regSPL = 17;
regBPL = 18;
regSIL = 19;
regDIL = 20;
regAX = 21;
regCX = 22;
regDX = 23;
regBX = 24;
regSP = 25;
regBP = 26;
regSI = 27;
regDI = 28;
regR8W = 29;
regR9W = 30;
regR10W = 31;
regR11W = 32;
regR12W = 33;
regR13W = 34;
regR14W = 35;
regR15W = 36;
regEAX = 37;
regECX = 38;
regEDX = 39;
regEBX = 40;
regESP = 41;
regEBP = 42;
regESI = 43;
regEDI = 44;
regR8D = 45;
regR9D = 46;
regR10D = 47;
regR11D = 48;
regR12D = 49;
regR13D = 50;
regR14D = 51;
regR15D = 52;
regRAX = 53;
regRCX = 54;
regRDX = 55;
regRBX = 56;
regRSP = 57;
regRBP = 58;
regRSI = 59;
regRDI = 60;
regR8 = 61;
regR9 = 62;
regR10 = 63;
regR11 = 64;
regR12 = 65;
regR13 = 66;
regR14 = 67;
regR15 = 68;
regES = 69;
regCS = 70;
regSS = 71;
regDS = 72;
regFS = 73;
regGS = 74;
regST0 = 75;
regST1 = 76;
regST2 = 77;
regST3 = 78;
regST4 = 79;
regST5 = 80;
regST6 = 81;
regST7 = 82;
regCR0 = 83;
regCR1 = 84;
regCR2 = 85;
regCR3 = 86;
regCR4 = 87;
regCR5 = 88;
regCR6 = 89;
regCR7 = 90;
regCR8 = 91;
regCR9 = 92;
regCR10 = 93;
regCR11 = 94;
regCR12 = 95;
regCR13 = 96;
regCR14 = 97;
regCR15 = 98;
regDR0 = 99;
regDR1 = 100;
regDR2 = 101;
regDR3 = 102;
regDR4 = 103;
regDR5 = 104;
regDR6 = 105;
regDR7 = 106;
regDR8 = 107;
regDR9 = 108;
regDR10 = 109;
regDR11 = 110;
regDR12 = 111;
regDR13 = 112;
regDR14 = 113;
regDR15 = 114;
regXMM0 = 115;
regXMM1 = 116;
regXMM2 = 117;
regXMM3 = 118;
regXMM4 = 119;
regXMM5 = 120;
regXMM6 = 121;
regXMM7 = 122;
regXMM8 = 123;
regXMM9 = 124;
regXMM10 = 125;
regXMM11 = 126;
regXMM12 = 127;
regXMM13 = 128;
regXMM14 = 129;
regXMM15 = 130;
regMMX0 = 131;
regMMX1 = 132;
regMMX2 = 133;
regMMX3 = 134;
regMMX4 = 135;
regMMX5 = 136;
regMMX6 = 137;
regMMX7 = 138;
regIP = 139;
regRIP = 140;
TYPE
Arg = OBJECT
PROCEDURE Print (w : Streams.Writer);
END Print;
END Arg;
ArgImm = OBJECT (Arg)
VAR
imm : HUGEINT;
PROCEDURE &New *(imm : HUGEINT);
BEGIN SELF.imm := imm;
END New;
PROCEDURE Print (w : Streams.Writer);
BEGIN PrintImm (imm, w);
END Print;
END ArgImm;
ArgReg = OBJECT (Arg)
VAR
reg : LONGINT;
PROCEDURE &New *(reg : LONGINT);
BEGIN SELF.reg := reg;
END New;
PROCEDURE Print (w : Streams.Writer);
BEGIN PrintReg (w, reg);
END Print;
END ArgReg;
ArgMem = OBJECT (Arg)
VAR
segment, reg, scale, base: LONGINT; disp : HUGEINT;
PROCEDURE &New *(segment, reg, scale , base: LONGINT; disp : HUGEINT);
BEGIN
SELF.segment := segment;
SELF.reg := reg;
SELF.scale := scale;
SELF.base := base;
SELF.disp := disp;
END New;
PROCEDURE Print (w : Streams.Writer);
BEGIN
IF segment # regNONE THEN
PrintReg (w, segment); w.String (":")
END;
w.String ("[");
IF reg # regNONE THEN
PrintReg (w, reg);
IF scale > 1 THEN w.String ("*"); w.Int (scale, 0) END;
END;
IF base = regNONE THEN
IF (reg = regNONE) THEN
PrintImm (disp, w);
ELSIF disp > 0 THEN
w.String (" + ");
PrintImm (disp, w);
ELSIF disp < 0 THEN
w.String (" - ");
PrintImm (-disp, w);
END
ELSE
IF (reg # regNONE) THEN
w.String (" + ");
END;
PrintReg (w, base);
IF disp > 0 THEN
w.String (" + ");
PrintImm (disp, w);
ELSIF disp < 0 THEN
w.String (" - ");
PrintImm (-disp, w);
END
END;
w.String ("]");
END Print;
END ArgMem;
AMD64Opcode = OBJECT (Decoder.Opcode)
VAR
prefixCount : LONGINT;
prefixes : SET;
instr: LONGINT;
arg : ARRAY maxArgs OF Arg;
hidePrefixes: BOOLEAN;
PROCEDURE &New*(proc : Decoder.ProcedureInfo; stream : Streams.Writer);
BEGIN
New^(proc, stream);
prefixCount := 0;
prefixes := {};
hidePrefixes := FALSE;
END New;
PROCEDURE PrintOpcodeBytes (w : Streams.Writer);
VAR
i : LONGINT;
BEGIN
FOR i := 0 TO LEN (code) - 1 DO
WriteHex8 (ORD (code[i]), w);
IF i < prefixCount THEN
w.String (" | ");
ELSE
w.String (" ");
END
END
END PrintOpcodeBytes;
PROCEDURE PrintInstruction (w : Streams.Writer);
BEGIN
IF ~hidePrefixes THEN
IF prREP IN prefixes THEN w.String ("REP ") END;
IF prREPN IN prefixes THEN w.String ("REPN ") END;
END;
IF prLOCK IN prefixes THEN w.String ("LOCK ") END;
CASE instr OF
| opInvalid: w.String ("Invalid");
| opReserved: w.String ("Reserved");
| opADC: w.String ("ADC");
| opADD: w.String ("ADD");
| opADDPD: w.String ("ADDPD");
| opADDPS: w.String ("ADDPS");
| opADDSD: w.String ("ADDSD");
| opADDSS: w.String ("ADDSS");
| opADDSUBPD: w.String ("ADDSUBPD");
| opADDSUBPS: w.String ("ADDSUBPS");
| opAND: w.String ("AND");
| opANDNPD: w.String ("ANDNPD");
| opANDNPS: w.String ("ANDNPS");
| opANDPD: w.String ("ANDPD");
| opANDPS: w.String ("ANDPS");
| opBSF: w.String ("BSF");
| opBSR: w.String ("BSR");
| opBSWAP: w.String ("BSWAP");
| opBT: w.String ("BT");
| opBTC: w.String ("BTC");
| opBTR: w.String ("BTR");
| opBTS: w.String ("BTS");
| opCALL: w.String ("CALL");
| opCBW: w.String ("CBW");
| opCDQ: w.String ("CDQ");
| opCDQE: w.String ("CDQE");
| opCLC: w.String ("CLC");
| opCLD: w.String ("CLD");
| opCLGI: w.String ("CLGI");
| opCLI: w.String ("CLI");
| opCLTS: w.String ("CLTS");
| opCMC: w.String ("CMC");
| opCMP: w.String ("CMP");
| opCMPPD: w.String ("CMPPD");
| opCMPPS: w.String ("CMPPS");
| opCMPSB: w.String ("CMPSB");
| opCMPSD: w.String ("CMPSD");
| opCMPSQ: w.String ("CMPSQ");
| opCMPSS: w.String ("CMPSS");
| opCMPSW: w.String ("CMPSW");
| opCMPXCHG: w.String ("CMPXCHG");
| opCMPXCHG16B: w.String ("CMPXCHG16B");
| opCMPXCHG8B: w.String ("CMPXCHG8B");
| opCOMISD: w.String ("COMISD");
| opCOMISS: w.String ("COMISS");
| opCPUID: w.String ("CPUID");
| opCQO: w.String ("CQO");
| opCVTDQ2PD: w.String ("CVTDQ2PD");
| opCVTDQ2PS: w.String ("CVTDQ2PS");
| opCVTPD2PI: w.String ("CVTPD2PI");
| opCVTPD2PS: w.String ("CVTPD2PS");
| opCVTPI2PD: w.String ("CVTPI2PD");
| opCVTPI2PS: w.String ("CVTPI2PS");
| opCVTPS2DQ: w.String ("CVTPS2DQ");
| opCVTPS2PD: w.String ("CVTPS2PD");
| opCVTPS2PI: w.String ("CVTPS2PI");
| opCVTSD2SI: w.String ("CVTSD2SI");
| opCVTSD2SS: w.String ("CVTSD2SS");
| opCVTSI2SD: w.String ("CVTSI2SD");
| opCVTSI2SS: w.String ("CVTSI2SS");
| opCVTSS2SD: w.String ("CVTSS2SD");
| opCVTSS2SI: w.String ("CVTSS2SI");
| opCVTTPD2DQ: w.String ("CVTTPD2DQ");
| opCVTTPD2PI: w.String ("CVTTPD2PI");
| opCVTTPS2DQ: w.String ("CVTTPS2DQ");
| opCVTTPS2PI: w.String ("CVTTPS2PI");
| opCVTTSD2SI: w.String ("CVTTSD2SI");
| opCVTTSS2SI: w.String ("CVTTSS2SI");
| opCWD: w.String ("CWD");
| opCWDE: w.String ("CWDE");
| opDEC: w.String ("DEC");
| opDIV: w.String ("DIV");
| opDIVPD: w.String ("DIVPD");
| opDIVPS: w.String ("DIVPS");
| opDIVSD: w.String ("DIVSD");
| opDIVSS: w.String ("DIVSS");
| opEMMS: w.String ("EMMS");
| opENTER: w.String ("ENTER");
| opF2XM1: w.String ("F2XM1");
| opFABS: w.String ("FABS");
| opFADD: w.String ("FADD");
| opFADDP: w.String ("FADDP");
| opFBLD: w.String ("FBLD");
| opFBSTP: w.String ("FBSTP");
| opFCHS: w.String ("FCHS");
| opFCMOVB: w.String ("FCMOVB");
| opFCMOVBE: w.String ("FCMOVBE");
| opFCMOVE: w.String ("FCMOVE");
| opFCMOVNB: w.String ("FCMOVNB");
| opFCMOVNBE: w.String ("FCMOVNBE");
| opFCMOVNE: w.String ("FCMOVNE");
| opFCMOVNU: w.String ("FCMOVNU");
| opFCMOVU: w.String ("FCMOVU");
| opFCOM: w.String ("FCOM");
| opFCOMI: w.String ("FCOMI");
| opFCOMIP: w.String ("FCOMIP");
| opFCOMP: w.String ("FCOMP");
| opFCOMPP: w.String ("FCOMPP");
| opFCOS: w.String ("FCOS");
| opFDECSTP: w.String ("FDECSTP");
| opFDIV: w.String ("FDIV");
| opFDIVP: w.String ("FDIVP");
| opFDIVR: w.String ("FDIVR");
| opFDIVRP: w.String ("FDIVRP");
| opFEMMS: w.String ("FEMMS");
| opFFREE: w.String ("FFREE");
| opFIADD: w.String ("FIADD");
| opFICOM: w.String ("FICOM");
| opFICOMP: w.String ("FICOMP");
| opFIDIV: w.String ("FIDIV");
| opFIDIVR: w.String ("FIDIVR");
| opFILD: w.String ("FILD");
| opFIMUL: w.String ("FIMUL");
| opFINCSTP: w.String ("FINCSTP");
| opFIST: w.String ("FIST");
| opFISTP: w.String ("FISTP");
| opFISTTP: w.String ("FISTTP");
| opFISUB: w.String ("FISUB");
| opFISUBR: w.String ("FISUBR");
| opFLD: w.String ("FLD");
| opFLD1: w.String ("FLD1");
| opFLDCW: w.String ("FLDCW");
| opFLDENV: w.String ("FLDENV");
| opFLDL2E: w.String ("FLDL2E");
| opFLDL2T: w.String ("FLDL2T");
| opFLDLG2: w.String ("FLDLG2");
| opFLDLN2: w.String ("FLDLN2");
| opFLDPI: w.String ("FLDPI");
| opFLDZ: w.String ("FLDZ");
| opFMUL: w.String ("FMUL");
| opFMULP: w.String ("FMULP");
| opFNCLEX: w.String ("FNCLEX");
| opFNINIT: w.String ("FNINIT");
| opFNOP: w.String ("FNOP");
| opFNSAVE: w.String ("FNSAVE");
| opFNSTCW: w.String ("FNSTCW");
| opFNSTENV: w.String ("FNSTENV");
| opFNSTSW: w.String ("FNSTSW");
| opFPATAN: w.String ("FPATAN");
| opFPREM: w.String ("FPREM");
| opFPREM1: w.String ("FPREM1");
| opFPTAN: w.String ("FPTAN");
| opFRNDINT: w.String ("FRNDINT");
| opFRSTOR: w.String ("FRSTOR");
| opFSCALE: w.String ("FSCALE");
| opFSIN: w.String ("FSIN");
| opFSINCOS: w.String ("FSINCOS");
| opFSQRT: w.String ("FSQRT");
| opFST: w.String ("FST");
| opFSTP: w.String ("FSTP");
| opFSUB: w.String ("FSUB");
| opFSUBP: w.String ("FSUBP");
| opFSUBR: w.String ("FSUBR");
| opFSUBRP: w.String ("FSUBRP");
| opFTST: w.String ("FTST");
| opFUCOM: w.String ("FUCOM");
| opFUCOMI: w.String ("FUCOMI");
| opFUCOMIP: w.String ("FUCOMIP");
| opFUCOMP: w.String ("FUCOMP");
| opFUCOMPP: w.String ("FUCOMPP");
| opFWAIT: w.String ("FWAIT");
| opFXAM: w.String ("FXAM");
| opFXCH: w.String ("FXCH");
| opFXRSTOR: w.String ("FXRSTOR");
| opFXSAVE: w.String ("FXSAVE");
| opFXTRACT: w.String ("FXTRACT");
| opFYL2X: w.String ("FYL2X");
| opFYL2XP1: w.String ("FYL2XP1");
| opHADDPD: w.String ("HADDPD");
| opHADDPS: w.String ("HADDPS");
| opHLT: w.String ("HLT");
| opHSUBPD: w.String ("HSUBPD");
| opHSUBPS: w.String ("HSUBPS");
| opIDIV: w.String ("IDIV");
| opIMUL: w.String ("IMUL");
| opIN: w.String ("IN");
| opINC: w.String ("INC");
| opINSB: w.String ("INSB");
| opINSD: w.String ("INSD");
| opINSW: w.String ("INSW");
| opINT: w.String ("INT");
| opINVD: w.String ("INVD");
| opINVLPG: w.String ("INVLPG");
| opINVLPGA: w.String ("INVLPGA");
| opIRET: w.String ("IRET");
| opIRETD: w.String ("IRETD");
| opIRETQ: w.String ("IRETQ");
| opJA: w.String ("JA");
| opJB: w.String ("JB");
| opJBE: w.String ("JBE");
| opJCXZ: w.String ("JCXZ");
| opJE: w.String ("JE");
| opJECXZ: w.String ("JECXZ");
| opJG: w.String ("JG");
| opJGE: w.String ("JGE");
| opJL: w.String ("JL");
| opJLE: w.String ("JLE");
| opJMP: w.String ("JMP");
| opJNB: w.String ("JNB");
| opJNBE: w.String ("JNBE");
| opJNE: w.String ("JNE");
| opJNO: w.String ("JNO");
| opJNP: w.String ("JNP");
| opJO: w.String ("JO");
| opJP: w.String ("JP");
| opJRCXZ: w.String ("JRCXZ");
| opJS: w.String ("JS");
| opLAHF: w.String ("LAHF");
| opLAR: w.String ("LAR");
| opLDDQU: w.String ("LDDQU");
| opLDMXCSR: w.String ("LDMXCSR");
| opLEA: w.String ("LEA");
| opLEAVE: w.String ("LEAVE");
| opLFENCE: w.String ("LFENCE");
| opLFS: w.String ("LFS");
| opLGDT: w.String ("LGDT");
| opLGS: w.String ("LGS");
| opLIDT: w.String ("LIDT");
| opLLDT: w.String ("LLDT");
| opLMSW: w.String ("LMSW");
| opLODSB: w.String ("LODSB");
| opLODSD: w.String ("LODSD");
| opLODSQ: w.String ("LODSQ");
| opLODSW: w.String ("LODSW");
| opLOOP: w.String ("LOOP");
| opLOOPE: w.String ("LOOPE");
| opLOOPNE: w.String ("LOOPNE");
| opLSL: w.String ("LSL");
| opLSS: w.String ("LSS");
| opLTR: w.String ("LTR");
| opMASKMOVDQU: w.String ("MASKMOVDQU");
| opMASKMOVQ: w.String ("MASKMOVQ");
| opMAXPD: w.String ("MAXPD");
| opMAXPS: w.String ("MAXPS");
| opMAXSD: w.String ("MAXSD");
| opMAXSS: w.String ("MAXSS");
| opMFENCE: w.String ("MFENCE");
| opMINPD: w.String ("MINPD");
| opMINPS: w.String ("MINPS");
| opMINSD: w.String ("MINSD");
| opMINSS: w.String ("MINSS");
| opMOV: w.String ("MOV");
| opMOVA: w.String ("MOVA");
| opMOVAPD: w.String ("MOVAPD");
| opMOVAPS: w.String ("MOVAPS");
| opMOVB: w.String ("MOVB");
| opMOVBE: w.String ("MOVBE");
| opMOVD: w.String ("MOVD");
| opMOVDDUP: w.String ("MOVDDUP");
| opMOVDQ2Q: w.String ("MOVDQ2Q");
| opMOVDQA: w.String ("MOVDQA");
| opMOVDQU: w.String ("MOVDQU");
| opMOVE: w.String ("MOVE");
| opMOVG: w.String ("MOVG");
| opMOVGE: w.String ("MOVGE");
| opMOVHLPS: w.String ("MOVHLPS");
| opMOVHPD: w.String ("MOVHPD");
| opMOVHPS: w.String ("MOVHPS");
| opMOVL: w.String ("MOVL");
| opMOVLE: w.String ("MOVLE");
| opMOVLHPS: w.String ("MOVLHPS");
| opMOVLPD: w.String ("MOVLPD");
| opMOVLPS: w.String ("MOVLPS");
| opMOVMSKPD: w.String ("MOVMSKPD");
| opMOVMSKPS: w.String ("MOVMSKPS");
| opMOVNB: w.String ("MOVNB");
| opMOVNBE: w.String ("MOVNBE");
| opMOVNE: w.String ("MOVNE");
| opMOVNO: w.String ("MOVNO");
| opMOVNP: w.String ("MOVNP");
| opMOVNTDQ: w.String ("MOVNTDQ");
| opMOVNTI: w.String ("MOVNTI");
| opMOVNTPD: w.String ("MOVNTPD");
| opMOVNTPS: w.String ("MOVNTPS");
| opMOVNTQ: w.String ("MOVNTQ");
| opMOVO: w.String ("MOVO");
| opMOVP: w.String ("MOVP");
| opMOVQ: w.String ("MOVQ");
| opMOVQ2DQ: w.String ("MOVQ2DQ");
| opMOVS: w.String ("MOVS");
| opMOVSB: w.String ("MOVSB");
| opMOVSD: w.String ("MOVSD");
| opMOVSHDUP: w.String ("MOVSHDUP");
| opMOVSLDUP: w.String ("MOVSLDUP");
| opMOVSQ: w.String ("MOVSQ");
| opMOVSS: w.String ("MOVSS");
| opMOVSW: w.String ("MOVSW");
| opMOVSX: w.String ("MOVSX");
| opMOVSXD: w.String ("MOVSXD");
| opMOVUPD: w.String ("MOVUPD");
| opMOVUPS: w.String ("MOVUPS");
| opMOVZX: w.String ("MOVZX");
| opMUL: w.String ("MUL");
| opMULPD: w.String ("MULPD");
| opMULPS: w.String ("MULPS");
| opMULSD: w.String ("MULSD");
| opMULSS: w.String ("MULSS");
| opNEG: w.String ("NEG");
| opNOP: w.String ("NOP");
| opNOT: w.String ("NOT");
| opOR: w.String ("OR");
| opORPD: w.String ("ORPD");
| opORPS: w.String ("ORPS");
| opOUT: w.String ("OUT");
| opOUTSB: w.String ("OUTSB");
| opOUTSD: w.String ("OUTSD");
| opOUTSW: w.String ("OUTSW");
| opPACKSSDW: w.String ("PACKSSDW");
| opPACKSSWB: w.String ("PACKSSWB");
| opPACKUSWB: w.String ("PACKUSWB");
| opPADDB: w.String ("PADDB");
| opPADDD: w.String ("PADDD");
| opPADDQ: w.String ("PADDQ");
| opPADDSB: w.String ("PADDSB");
| opPADDSW: w.String ("PADDSW");
| opPADDUSB: w.String ("PADDUSB");
| opPADDUSW: w.String ("PADDUSW");
| opPADDW: w.String ("PADDW");
| opPAND: w.String ("PAND");
| opPANDN: w.String ("PANDN");
| opPAUSE: w.String ("PAUSE");
| opPAVGB: w.String ("PAVGB");
| opPAVGUSB: w.String ("PAVGUSB");
| opPAVGW: w.String ("PAVGW");
| opPCMPEQB: w.String ("PCMPEQB");
| opPCMPEQD: w.String ("PCMPEQD");
| opPCMPEQW: w.String ("PCMPEQW");
| opPCMPGTB: w.String ("PCMPGTB");
| opPCMPGTD: w.String ("PCMPGTD");
| opPCMPGTW: w.String ("PCMPGTW");
| opPEXTRW: w.String ("PEXTRW");
| opPF2ID: w.String ("PF2ID");
| opPF2IW: w.String ("PF2IW");
| opPFACC: w.String ("PFACC");
| opPFADD: w.String ("PFADD");
| opPFCMPEQ: w.String ("PFCMPEQ");
| opPFCMPGE: w.String ("PFCMPGE");
| opPFCMPGT: w.String ("PFCMPGT");
| opPFMAX: w.String ("PFMAX");
| opPFMIN: w.String ("PFMIN");
| opPFMUL: w.String ("PFMUL");
| opPFNACC: w.String ("PFNACC");
| opPFPNACC: w.String ("PFPNACC");
| opPFRCP: w.String ("PFRCP");
| opPFRCPIT1: w.String ("PFRCPIT1");
| opPFRSQIT1: w.String ("PFRSQIT1");
| opPFRSQRT: w.String ("PFRSQRT");
| opPFSUB: w.String ("PFSUB");
| opPFSUBR: w.String ("PFSUBR");
| opPI2FD: w.String ("PI2FD");
| opPI2FW: w.String ("PI2FW");
| opPINSRW: w.String ("PINSRW");
| opPMADDWD: w.String ("PMADDWD");
| opPMAXSW: w.String ("PMAXSW");
| opPMAXUB: w.String ("PMAXUB");
| opPMINSW: w.String ("PMINSW");
| opPMINUB: w.String ("PMINUB");
| opPMOVMSKB: w.String ("PMOVMSKB");
| opPMULHRW: w.String ("PMULHRW");
| opPMULHUW: w.String ("PMULHUW");
| opPMULHW: w.String ("PMULHW");
| opPMULLW: w.String ("PMULLW");
| opPMULUDQ: w.String ("PMULUDQ");
| opPOP: w.String ("POP");
| opPOPF: w.String ("POPF");
| opPOPFD: w.String ("POPFD");
| opPOPFQ: w.String ("POPFQ");
| opPOR: w.String ("POR");
| opPREFETCH: w.String ("PREFETCH");
| opPREFETCHNTA: w.String ("PREFETCHNTA");
| opPREFETCHT0: w.String ("PREFETCHT0");
| opPREFETCHT1: w.String ("PREFETCHT1");
| opPREFETCHT2: w.String ("PREFETCHT2");
| opPREFETCHW: w.String ("PREFETCHW");
| opPSADBW: w.String ("PSADBW");
| opPSHUFD: w.String ("PSHUFD");
| opPSHUFHW: w.String ("PSHUFHW");
| opPSHUFLW: w.String ("PSHUFLW");
| opPSHUFW: w.String ("PSHUFW");
| opPSLLD: w.String ("PSLLD");
| opPSLLDQ: w.String ("PSLLDQ");
| opPSLLQ: w.String ("PSLLQ");
| opPSLLW: w.String ("PSLLW");
| opPSRAD: w.String ("PSRAD");
| opPSRAW: w.String ("PSRAW");
| opPSRLD: w.String ("PSRLD");
| opPSRLDQ: w.String ("PSRLDQ");
| opPSRLQ: w.String ("PSRLQ");
| opPSRLW: w.String ("PSRLW");
| opPSUBB: w.String ("PSUBB");
| opPSUBD: w.String ("PSUBD");
| opPSUBQ: w.String ("PSUBQ");
| opPSUBSB: w.String ("PSUBSB");
| opPSUBSW: w.String ("PSUBSW");
| opPSUBUSB: w.String ("PSUBUSB");
| opPSUBUSW: w.String ("PSUBUSW");
| opPSUBW: w.String ("PSUBW");
| opPSWAPD: w.String ("PSWAPD");
| opPUNPCKHBW: w.String ("PUNPCKHBW");
| opPUNPCKHDQ: w.String ("PUNPCKHDQ");
| opPUNPCKHQDQ: w.String ("PUNPCKHQDQ");
| opPUNPCKHWD: w.String ("PUNPCKHWD");
| opPUNPCKLBW: w.String ("PUNPCKLBW");
| opPUNPCKLDQ: w.String ("PUNPCKLDQ");
| opPUNPCKLQDQ: w.String ("PUNPCKLQDQ");
| opPUNPCKLWD: w.String ("PUNPCKLWD");
| opPUSH: w.String ("PUSH");
| opPUSHF: w.String ("PUSHF");
| opPUSHFD: w.String ("PUSHFD");
| opPUSHFQ: w.String ("PUSHFQ");
| opPXOR: w.String ("PXOR");
| opRCL: w.String ("RCL");
| opRCPPS: w.String ("RCPPS");
| opRCPSS: w.String ("RCPSS");
| opRCR: w.String ("RCR");
| opRDMSR: w.String ("RDMSR");
| opRDPMC: w.String ("RDPMC");
| opRDTSC: w.String ("RDTSC");
| opRDTSCP: w.String ("RDTSCP");
| opRET: w.String ("RET");
| opROL: w.String ("ROL");
| opROR: w.String ("ROR");
| opRSM: w.String ("RSM");
| opRSQRTPS: w.String ("RSQRTPS");
| opRSQRTSS: w.String ("RSQRTSS");
| opSAHF: w.String ("SAHF");
| opSAR: w.String ("SAR");
| opSBB: w.String ("SBB");
| opSCASB: w.String ("SCASB");
| opSCASD: w.String ("SCASD");
| opSCASQ: w.String ("SCASQ");
| opSCASW: w.String ("SCASW");
| opSETA: w.String ("SETA");
| opSETB: w.String ("SETB");
| opSETBE: w.String ("SETBE");
| opSETE: w.String ("SETE");
| opSETG: w.String ("SETG");
| opSETGE: w.String ("SETGE");
| opSETL: w.String ("SETL");
| opSETLE: w.String ("SETLE");
| opSETNB: w.String ("SETNB");
| opSETNBE: w.String ("SETNBE");
| opSETNE: w.String ("SETNE");
| opSETNO: w.String ("SETNO");
| opSETNP: w.String ("SETNP");
| opSETO: w.String ("SETO");
| opSETP: w.String ("SETP");
| opSETS: w.String ("SETS");
| opSFENCE: w.String ("SFENCE");
| opSGDT: w.String ("SGDT");
| opSHL: w.String ("SHL");
| opSHLD: w.String ("SHLD");
| opSHR: w.String ("SHR");
| opSHRD: w.String ("SHRD");
| opSHUFPD: w.String ("SHUFPD");
| opSHUFPS: w.String ("SHUFPS");
| opSIDT: w.String ("SIDT");
| opSKINIT: w.String ("SKINIT");
| opSLDT: w.String ("SLDT");
| opSMSW: w.String ("SMSW");
| opSQRTPD: w.String ("SQRTPD");
| opSQRTPS: w.String ("SQRTPS");
| opSQRTSD: w.String ("SQRTSD");
| opSQRTSS: w.String ("SQRTSS");
| opSTC: w.String ("STC");
| opSTD: w.String ("STD");
| opSTGI: w.String ("STGI");
| opSTI: w.String ("STI");
| opSTMXCSR: w.String ("STMXCSR");
| opSTOSB: w.String ("STOSB");
| opSTOSD: w.String ("STOSD");
| opSTOSQ: w.String ("STOSQ");
| opSTOSW: w.String ("STOSW");
| opSTR: w.String ("STR");
| opSUB: w.String ("SUB");
| opSUBPD: w.String ("SUBPD");
| opSUBPS: w.String ("SUBPS");
| opSUBSD: w.String ("SUBSD");
| opSUBSS: w.String ("SUBSS");
| opSWAPGS: w.String ("SWAPGS");
| opSYSCALL: w.String ("SYSCALL");
| opSYSRET: w.String ("SYSRET");
| opTEST: w.String ("TEST");
| opUCOMISD: w.String ("UCOMISD");
| opUCOMISS: w.String ("UCOMISS");
| opUD2: w.String ("UD2");
| opUNPCKHPD: w.String ("UNPCKHPD");
| opUNPCKHPS: w.String ("UNPCKHPS");
| opUNPCKLPD: w.String ("UNPCKLPD");
| opUNPCKLPS: w.String ("UNPCKLPS");
| opVERR: w.String ("VERR");
| opVERW: w.String ("VERW");
| opVMLOAD: w.String ("VMLOAD");
| opVMMCALL: w.String ("VMMCALL");
| opVMRUN: w.String ("VMRUN");
| opVMSAVE: w.String ("VMSAVE");
| opWBINVD: w.String ("WBINVD");
| opWRMSR: w.String ("WRMSR");
| opXADD: w.String ("XADD");
| opXCHG: w.String ("XCHG");
| opXLAT: w.String ("XLAT");
| opXOR: w.String ("XOR");
| opXORPD: w.String ("XORPD");
| opXORPS: w.String ("XORPS");
END;
END PrintInstruction;
PROCEDURE PrintArguments (w : Streams.Writer);
VAR
i: LONGINT;
BEGIN
FOR i := 0 TO maxArgs - 1 DO
IF arg[i] # NIL THEN
IF i > 0 THEN w.String (", ") END;
arg[i].Print (w);
END
END
END PrintArguments;
PROCEDURE PrintVariables (w : Streams.Writer);
VAR
i, count: LONGINT;
argMem: ArgMem;
field : Decoder.FieldInfo;
BEGIN
count := 0;
FOR i := 0 TO maxArgs - 1 DO
IF (arg[i] # NIL) & (arg[i] IS ArgMem) THEN
argMem := arg[i](ArgMem);
IF (argMem.reg = regRBP) OR (argMem.reg = regEBP) THEN
field := proc.GetFieldAtOffset(SHORT (argMem.disp));
IF field # NIL THEN
field.AddMarkerPosition(w.Pos());
IF count > 0 THEN
w.String(", ")
END;
w.String(field.name);
w.String(": ");
argMem.Print (w);
INC (count);
END
END
END
END
END PrintVariables;
END AMD64Opcode;
AMD64Decoder = OBJECT (Decoder.Decoder)
PROCEDURE NewOpcode() : Decoder.Opcode;
VAR
opcode : AMD64Opcode;
BEGIN
NEW(opcode, currentProc, outputStreamWriter);
RETURN opcode
END NewOpcode;
PROCEDURE DecodeThis(opcode : Decoder.Opcode);
VAR
opc : AMD64Opcode;
byte, code, arg, mod, segment, reg, rm, scale, index, base, disp: LONGINT;
modRM : BOOLEAN;
PROCEDURE ReadImm8 (): LONGINT;
BEGIN
RETURN ORD (ReadChar ());
END ReadImm8;
PROCEDURE ReadImm16 (): LONGINT;
BEGIN
RETURN ReadInt ();
END ReadImm16;
PROCEDURE ReadImm32 (): LONGINT;
BEGIN
RETURN ReadLInt ();
END ReadImm32;
PROCEDURE ReadImm64 (): HUGEINT;
BEGIN
RETURN ReadHInt ();
END ReadImm64;
PROCEDURE ReadOffset8 (): LONGINT;
VAR
offset: LONGINT;
BEGIN
offset := ORD (ReadChar ());
IF offset >= 080H THEN DEC (offset, 100H) END;
RETURN offset;
END ReadOffset8;
PROCEDURE ReadOffset16 (): LONGINT;
VAR
offset: LONGINT;
BEGIN
offset := ReadInt ();
IF offset >= 08000H THEN DEC (offset, 10000H) END;
RETURN offset;
END ReadOffset16;
PROCEDURE ReadOffset32 (): LONGINT;
BEGIN
RETURN ReadLInt ();
END ReadOffset32;
PROCEDURE ReadOffset64 (): HUGEINT;
BEGIN
RETURN ReadHInt ();
END ReadOffset64;
PROCEDURE ReadHInt (): HUGEINT;
VAR
value: HUGEINT;
BEGIN
SYSTEM.PUT (SYSTEM.ADR (value), ReadLInt ());
SYSTEM.PUT (SYSTEM.ADR (value) + 4, ReadLInt ());
RETURN value;
END ReadHInt;
PROCEDURE Invalid;
BEGIN
Instr (opInvalid);
Bug (code, 0);
END Invalid;
PROCEDURE Reserved;
BEGIN
Instr (opReserved);
END Reserved;
PROCEDURE DecodePrefixes;
BEGIN
LOOP
byte := ORD (ReadChar ());
CASE byte OF
| 066H: INCL (opc.prefixes, prOperand);
| 067H: INCL (opc.prefixes, prAddress);
| 02EH: INCL (opc.prefixes, prCS);
| 03EH: INCL (opc.prefixes, prDS);
| 026H: INCL (opc.prefixes, prES);
| 064H: INCL (opc.prefixes, prFS);
| 065H: INCL (opc.prefixes, prGS);
| 036H: INCL (opc.prefixes, prSS);
| 0F0H: INCL (opc.prefixes, prLOCK);
| 0F3H: INCL (opc.prefixes, prREP);
| 0F2H: INCL (opc.prefixes, prREPN);
ELSE
IF byte DIV 10H = 4H THEN
INCL (opc.prefixes, prREX);
IF byte DIV 8H MOD 2H # 0 THEN INCL (opc.prefixes, prREXW) END;
IF byte DIV 4H MOD 2H # 0 THEN INCL (opc.prefixes, prREXR) END;
IF byte DIV 2H MOD 2H # 0 THEN INCL (opc.prefixes, prREXX) END;
IF byte MOD 2H # 0 THEN INCL (opc.prefixes, prREXB) END;
byte := ORD (ReadChar ());
INC (opc.prefixCount);
END;
RETURN;
END;
INC (opc.prefixCount);
END;
END DecodePrefixes;
PROCEDURE Prefix (prefix: LONGINT): BOOLEAN;
BEGIN
RETURN prefix IN opc.prefixes;
END Prefix;
PROCEDURE Instr (instr : LONGINT);
BEGIN
opc.instr := instr;
END Instr;
PROCEDURE InstrOp (instr16, instr32, instr64 : LONGINT);
BEGIN
IF Prefix (prREXW) THEN
Instr (instr64);
ELSIF Prefix (prOperand) THEN
Instr (instr16);
ELSE
Instr (instr32);
END
END InstrOp;
PROCEDURE ModRM;
BEGIN
IF modRM THEN RETURN ELSE modRM := TRUE END;
byte := ORD (ReadChar ());
mod := byte DIV 40H MOD 4H;
reg := byte DIV 8H MOD 8H;
rm := byte MOD 8H;
IF (mod # 3) & (rm = 4) THEN
byte := ORD (ReadChar ());
scale := byte DIV 40H MOD 4H;
index := byte DIV 8H MOD 8H;
base := byte MOD 8H;
ELSE
base := 0;
END;
IF mod = 1 THEN
disp := ORD (ReadChar ());
IF disp > 07FH THEN DEC (disp, 0100H) END;
ELSIF (mod = 2) OR ((mod = 0) & (rm = 5)) OR (base = 5) THEN
disp := ReadLInt ();
ELSE
disp := 0;
END
END ModRM;
PROCEDURE GetOperandSize () : LONGINT;
BEGIN
IF Prefix (prREXW) THEN
RETURN 64;
ELSIF Prefix (prOperand) THEN
RETURN 16;
ELSE
RETURN 32;
END
END GetOperandSize;
PROCEDURE GetOperandReg (offset: LONGINT): LONGINT;
BEGIN
IF Prefix (prREXW) THEN
RETURN regRAX + offset;
ELSIF Prefix (prOperand) THEN
RETURN regAX + offset;
ELSE
RETURN regEAX + offset;
END
END GetOperandReg;
PROCEDURE GetReg (base, offset : LONGINT; extension : BOOLEAN) : LONGINT;
BEGIN
IF base = regES THEN
IF offset >= 6 THEN Invalid; END;
RETURN base + offset;
ELSIF extension THEN
IF base = regrAX THEN
RETURN GetOperandReg (offset + 8)
ELSE
RETURN base + offset + 8
END
ELSIF (base = regAL) & (offset >= 4) & (prREX IN opc.prefixes) THEN
RETURN regSPL - 4 + offset;
ELSIF base = regrAX THEN
RETURN GetOperandReg (offset)
ELSE
RETURN base + offset;
END
END GetReg;
PROCEDURE GetAddressReg (offset: LONGINT; extension: BOOLEAN): LONGINT;
BEGIN
IF extension THEN
IF prAddress IN opc.prefixes THEN RETURN regR8D + offset ELSE RETURN regR8 + offset END;
ELSE
IF prAddress IN opc.prefixes THEN RETURN regEAX + offset ELSE RETURN regRAX + offset END;
END
END GetAddressReg;
PROCEDURE AddImm (imm: HUGEINT);
VAR
argImm: ArgImm;
BEGIN
NEW (argImm, imm); opc.arg[arg] := argImm; INC (arg);
END AddImm;
PROCEDURE AddReg (reg: LONGINT);
VAR
argReg: ArgReg;
BEGIN
NEW (argReg, reg); opc.arg[arg] := argReg; INC (arg);
END AddReg;
PROCEDURE AddRMReg (base: LONGINT);
BEGIN
ModRM; AddReg (GetReg (base, reg, prREXR IN opc.prefixes));
END AddRMReg;
PROCEDURE AddMem (segment, reg, scale , base: LONGINT; disp: HUGEINT);
VAR
argMem: ArgMem;
BEGIN
NEW (argMem, segment, reg, scale, base, disp); opc.arg[arg] := argMem; INC (arg);
END AddMem;
PROCEDURE AddModMem;
VAR
reg, baseReg, scaling : LONGINT;
BEGIN
ModRM;
IF mod = 3 THEN
Invalid; RETURN;
ELSIF (mod = 0) & (rm = 5) THEN
IF Prefix (prREXB) & Prefix (prAddress) THEN reg := regIP ELSE reg := regRIP END;
scaling := 1;
baseReg := regNONE;
ELSIF rm = 4 THEN
IF (index = 4) & ~Prefix (prREXX) THEN
reg := regNONE
ELSE
reg := GetAddressReg (index, Prefix (prREXX));
END;
IF (base = 5) & (mod = 0) THEN
baseReg := regNONE
ELSE
baseReg := GetAddressReg (base, Prefix (prREXB));
END;
CASE scale OF
| 0: scaling := 1;
| 1: scaling := 2;
| 2: scaling := 4;
| 3: scaling := 8;
END
ELSE
reg := GetAddressReg (rm, Prefix (prREXB));
scaling := 1;
baseReg := regNONE;
END;
AddMem (segment, reg, scaling, baseReg, disp);
END AddModMem;
PROCEDURE AddModRM (base: LONGINT);
BEGIN
ModRM;
IF mod = 3 THEN
AddReg (GetReg (base, rm, Prefix (prREXB)));
ELSE
AddModMem;
END
END AddModRM;
PROCEDURE AddFPReg (offset: LONGINT);
BEGIN
AddReg (regST0 + offset);
END AddFPReg;
PROCEDURE AL; BEGIN AddReg (regAL) END AL;
PROCEDURE CL; BEGIN AddReg (regCL) END CL;
PROCEDURE Cdq; BEGIN AddRMReg (regCR0) END Cdq;
PROCEDURE Ddq; BEGIN AddRMReg (regDR0) END Ddq;
PROCEDURE DX; BEGIN AddReg (regDX) END DX;
PROCEDURE eAX; BEGIN IF GetOperandSize () = 16 THEN AddReg (regAX) ELSE AddReg (regEAX) END; END eAX;
PROCEDURE Eb; BEGIN AddModRM (regAL) END Eb;
PROCEDURE Ed; BEGIN AddModRM (regEAX) END Ed;
PROCEDURE Edq; BEGIN IF GetOperandSize () = 64 THEN AddModRM (regRAX) ELSE AddModRM (regEAX) END END Edq;
PROCEDURE Ev; BEGIN AddModRM (regrAX) END Ev;
PROCEDURE Ew; BEGIN AddModRM (regAX) END Ew;
PROCEDURE FS; BEGIN AddReg (regFS) END FS;
PROCEDURE Fv; END Fv;
PROCEDURE Gb; BEGIN AddRMReg (regAL) END Gb;
PROCEDURE Gd; BEGIN AddRMReg (regEAX) END Gd;
PROCEDURE Gdq; BEGIN IF GetOperandSize () = 64 THEN AddRMReg (regRAX) ELSE AddRMReg (regEAX) END END Gdq;
PROCEDURE Gv; BEGIN AddRMReg (regrAX) END Gv;
PROCEDURE Gz; BEGIN IF GetOperandSize () = 16 THEN AddRMReg (regAX) ELSE AddRMReg (regEAX) END END Gz;
PROCEDURE Ib; BEGIN AddImm (ReadImm8 ()) END Ib;
PROCEDURE Iv;
BEGIN
CASE GetOperandSize () OF
| 16: AddImm (ReadImm16 ());
| 32: AddImm (ReadImm32 ());
| 64: AddImm (ReadImm64 ());
END;
END Iv;
PROCEDURE Iw; BEGIN AddImm (ReadInt ()) END Iw;
PROCEDURE Iz; BEGIN IF GetOperandSize () = 16 THEN AddImm (ReadImm16 ()) ELSE AddImm (ReadImm32 ()) END END Iz;
PROCEDURE Jb; BEGIN AddImm (ReadOffset8 ()) END Jb;
PROCEDURE Jz; BEGIN IF GetOperandSize () = 16 THEN AddImm (ReadOffset16 ()) ELSE AddImm (ReadOffset32 ()) END END Jz;
PROCEDURE M; BEGIN AddModMem () END M;
PROCEDURE Mb; BEGIN AddModMem () END Mb;
PROCEDURE Md; BEGIN AddModMem () END Md;
PROCEDURE Mdq; BEGIN AddModMem () END Mdq;
PROCEDURE Mp; BEGIN AddModMem () END Mp;
PROCEDURE Mq; BEGIN AddModMem () END Mq;
PROCEDURE Ms; BEGIN AddModMem () END Ms;
PROCEDURE MwRv; BEGIN AddModRM (regrAX) END MwRv;
PROCEDURE Ob; BEGIN AddMem (regNONE, regNONE, 1, regNONE, ReadOffset8 ()) END Ob;
PROCEDURE Ov;
BEGIN
CASE GetOperandSize () OF
| 16: AddMem (regNONE, regNONE, 1, regNONE, ReadOffset16 ());
| 32: AddMem (regNONE, regNONE, 1, regNONE, ReadOffset32 ());
| 64: AddMem (regNONE, regNONE, 1, regNONE, ReadOffset64 ());
END;
END Ov;
PROCEDURE Pq; BEGIN AddRMReg (regMMX0) END Pq;
PROCEDURE Pdq; BEGIN AddRMReg (regMMX0) END Pdq;
PROCEDURE PRq; BEGIN ModRM; IF mod = 3 THEN AddModRM (regMMX0) ELSE Invalid END END PRq;
PROCEDURE Qd; BEGIN AddModRM (regMMX0) END Qd;
PROCEDURE Qq; BEGIN AddModRM (regMMX0) END Qq;
PROCEDURE rAX; BEGIN AddReg (GetOperandReg (regrAX)) END rAX;
PROCEDURE Rdq; BEGIN AddModRM (regRAX) END Rdq;
PROCEDURE Sw; BEGIN AddRMReg (regES) END Sw;
PROCEDURE Xb; BEGIN AddMem (regNONE, GetAddressReg (regrSI, FALSE), 1, regNONE, 0) END Xb;
PROCEDURE Xv; BEGIN AddMem (regNONE, GetAddressReg (regrSI, FALSE), 1, regNONE, 0) END Xv;
PROCEDURE Xz; BEGIN AddMem (regNONE, GetAddressReg (regrSI, FALSE), 1, regNONE, 0) END Xz;
PROCEDURE Yb; BEGIN AddMem (regNONE, GetAddressReg (regrDI, FALSE), 1, regNONE, 0) END Yb;
PROCEDURE Yv; BEGIN AddMem (regNONE, GetAddressReg (regrDI, FALSE), 1, regNONE, 0) END Yv;
PROCEDURE Yz; BEGIN AddMem (regNONE, GetAddressReg (regrDI, FALSE), 1, regNONE, 0) END Yz;
PROCEDURE Vdq; BEGIN AddRMReg (regXMM0) END Vdq;
PROCEDURE Vdqsd; BEGIN AddRMReg (regXMM0) END Vdqsd;
PROCEDURE Vdqss; BEGIN AddRMReg (regXMM0) END Vdqss;
PROCEDURE Vps; BEGIN AddRMReg (regXMM0) END Vps;
PROCEDURE Vpd; BEGIN AddRMReg (regXMM0) END Vpd;
PROCEDURE Vq; BEGIN AddRMReg (regXMM0) END Vq;
PROCEDURE VRdq; BEGIN ModRM; IF mod = 3 THEN AddModRM (regXMM0) ELSE Invalid END END VRdq;
PROCEDURE VRpd; BEGIN ModRM; IF mod = 3 THEN AddModRM (regXMM0) ELSE Invalid END END VRpd;
PROCEDURE VRps; BEGIN ModRM; IF mod = 3 THEN AddModRM (regXMM0) ELSE Invalid END END VRps;
PROCEDURE VRq; BEGIN ModRM; IF mod = 3 THEN AddModRM (regXMM0) ELSE Invalid END END VRq;
PROCEDURE Vsd; BEGIN AddRMReg (regXMM0) END Vsd;
PROCEDURE Vss; BEGIN AddRMReg (regXMM0) END Vss;
PROCEDURE Wdq; BEGIN AddModRM (regXMM0) END Wdq;
PROCEDURE Wpd; BEGIN AddModRM (regXMM0) END Wpd;
PROCEDURE Wq; BEGIN AddModRM (regXMM0) END Wq;
PROCEDURE Wps; BEGIN AddModRM (regXMM0) END Wps;
PROCEDURE Wsd; BEGIN AddModRM (regXMM0) END Wsd;
PROCEDURE Wss; BEGIN AddModRM (regXMM0) END Wss;
PROCEDURE Type1 (instr, offset : LONGINT);
BEGIN
Instr (instr);
CASE offset OF
| 0: Eb; Gb;
| 1: Ev; Gv;
| 2: Gb; Eb;
| 3: Gv; Ev;
| 4: AL; Ib;
| 5: rAX; Iz;
END
END Type1;
PROCEDURE Type2 (instr, offset : LONGINT);
BEGIN
Instr (instr);
IF prREXB IN opc.prefixes THEN INC (offset, 8) END;
IF GetOperandSize () = 16 THEN
AddReg (regAX + offset);
ELSE
AddReg (regRAX + offset);
END
END Type2;
PROCEDURE Type3 (instr : LONGINT);
BEGIN
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (instr); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (instr); Pq; Qq; END;
END Type3;
PROCEDURE Group1;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opADD);
| 1: Instr (opOR);
| 2: Instr (opADC);
| 3: Instr (opSBB);
| 4: Instr (opAND);
| 5: Instr (opSUB);
| 6: Instr (opXOR);
| 7: Instr (opCMP);
END;
CASE code OF
| 080H: Eb; Ib;
| 081H: Ev; Iz;
| 082H: Invalid;
| 083H: Ev; Ib;
END
END Group1;
PROCEDURE Group1a;
BEGIN
ModRM;
IF reg = 0 THEN
Instr (opPOP); Ev;
ELSE
Invalid;
END
END Group1a;
PROCEDURE Group2;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opROL);
| 1: Instr (opROR);
| 2: Instr (opRCL);
| 3: Instr (opRCR);
| 4: Instr (opSHL);
| 5: Instr (opSHR);
| 6: Instr (opSHL);
| 7: Instr (opSHR);
END;
CASE code OF
| 0C0H: Eb; Ib;
| 0C1H: Ev; Ib;
| 0D0H: Eb; AddImm (1);
| 0D1H: Ev; AddImm (1);
| 0D2H: Eb; AddReg (regCL);
| 0D3H: Ev; AddReg (regCL);
END
END Group2;
PROCEDURE Group3;
BEGIN
ModRM;
CASE reg OF
| 0..1: Instr (opTEST);
| 2: Instr (opNOT);
| 3: Instr (opNEG);
| 4: Instr (opMUL);
| 5: Instr (opIMUL);
| 6: Instr (opDIV);
| 7: Instr (opIDIV);
END;
CASE code OF
| 0F6H: Eb; IF reg <= 1 THEN Ib END;
| 0F7H: Ev; IF reg <= 1 THEN Iz END;
END
END Group3;
PROCEDURE Group4;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opINC);
| 1: Instr (opDEC);
ELSE
Invalid; RETURN;
END;
Eb;
END Group4;
PROCEDURE Group5;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opINC); Ev;
| 1: Instr (opDEC); Ev;
| 2: Instr (opCALL); Ev;
| 3: Instr (opCALL); Mp;
| 4: Instr (opJMP); Ev;
| 5: Instr (opJMP); Mp;
| 6: Instr (opPUSH); Ev;
ELSE
Invalid;
END;
END Group5;
PROCEDURE Group6;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opSLDT); MwRv;
| 1: Instr (opSTR); MwRv;
| 2: Instr (opLLDT); Ew;
| 3: Instr (opLTR); Ew;
| 4: Instr (opVERR); Ew;
| 5: Instr (opVERW); Ew;
ELSE
Invalid;
END;
END Group6;
PROCEDURE Group7;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opSGDT); Ms;
| 1: Instr (opSIDT); Ms;
| 2: Instr (opLGDT); Ms;
| 3: IF mod = 3 THEN GroupModRM ELSE Instr (opLIDT); Ms END;
| 4: Instr (opSMSW); MwRv;
| 6: Instr (opLMSW); Ew;
| 7: IF mod = 3 THEN GroupModRM ELSE Instr (opINVLPG); Mb END;
ELSE
Invalid;
END;
END Group7;
PROCEDURE Group8;
BEGIN
ModRM;
CASE reg OF
| 4: Instr (opBT);
| 5: Instr (opBTS);
| 6: Instr (opBTR);
| 7: Instr (opBTC);
ELSE
Invalid; RETURN;
END;
Ev; Ib;
END Group8;
PROCEDURE Group9;
BEGIN
ModRM;
IF reg = 1 THEN
IF Prefix (prREXW) THEN
Instr (opCMPXCHG16B); Mdq;
ELSE
Instr (opCMPXCHG8B); Mq;
END;
ELSE
Invalid;
END;
END Group9;
PROCEDURE Group10;
BEGIN
Invalid;
END Group10;
PROCEDURE Group11;
BEGIN
ModRM;
IF reg = 0 THEN
Instr (opMOV);
ELSE
Invalid; RETURN;
END;
CASE code OF
| 0C6H: Eb; Ib;
| 0C7H: Ev; Iz;
END
END Group11;
PROCEDURE Group12;
BEGIN
ModRM;
IF Prefix (prF2) OR Prefix (prF3) THEN
Invalid; RETURN;
END;
CASE reg OF
| 2: Instr (opPSRLW);
| 4: Instr (opPSRAW);
| 6: Instr (opPSLLW);
ELSE
Invalid; RETURN;
END;
IF Prefix (pr66) THEN
VRdq; Ib;
ELSE
PRq; Ib;
END;
END Group12;
PROCEDURE Group13;
BEGIN
ModRM;
IF Prefix (prF2) OR Prefix (prF3) THEN
Invalid; RETURN;
END;
CASE reg OF
| 2: Instr (opPSRLD);
| 4: Instr (opPSRAD);
| 6: Instr (opPSLLD);
ELSE
Invalid; RETURN;
END;
IF Prefix (pr66) THEN
VRdq; Ib;
ELSE
PRq; Ib;
END;
END Group13;
PROCEDURE Group14;
BEGIN
ModRM;
IF Prefix (prF2) OR Prefix (prF3) THEN
Invalid; RETURN;
END;
CASE reg OF
| 2: Instr (opPSRLQ);
| 3: IF Prefix (pr66) THEN Instr (opPSRLDQ) ELSE Invalid; RETURN; END;
| 6: Instr (opPSLLQ);
| 7: IF Prefix (pr66) THEN Instr (opPSLLDQ) ELSE Invalid; RETURN; END;
ELSE
Invalid; RETURN;
END;
IF Prefix (pr66) THEN
VRdq; Ib;
ELSE
PRq; Ib;
END;
END Group14;
PROCEDURE Group15;
BEGIN
ModRM;
IF Prefix (pr66) OR Prefix (prF2) OR Prefix (prF3) THEN
Invalid; RETURN;
END;
CASE reg OF
| 0: Instr (opFXSAVE); M;
| 1: Instr (opFXRSTOR); M;
| 2: Instr (opLDMXCSR); Md;
| 3: Instr (opSTMXCSR); Md;
| 5..7: GroupModRM;
ELSE
Invalid;
END;
END Group15;
PROCEDURE Group16;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opPREFETCHNTA);
| 1: Instr (opPREFETCHT0);
| 2: Instr (opPREFETCHT1);
| 3: Instr (opPREFETCHT2);
| 4..7: Instr (opNOP);
END;
END Group16;
PROCEDURE GroupP;
BEGIN
ModRM;
CASE reg OF
| 0: Instr (opPREFETCH);
| 1, 3: Instr (opPREFETCHW);
ELSE
Instr (opPREFETCH);
END;
END GroupP;
PROCEDURE GroupModRM;
BEGIN
ModRM;
IF code = 0F01H THEN
CASE reg OF
3:
CASE rm OF
| 0: Instr (opVMRUN);
| 1: Instr (opVMMCALL);
| 2: Instr (opVMLOAD);
| 3: Instr (opVMSAVE);
| 4: Instr (opSTGI);
| 5: Instr (opCLGI);
| 6: Instr (opSKINIT);
| 7: Instr (opINVLPGA);
END;
| 7:
CASE rm OF
| 0: Instr (opSWAPGS);
| 1: Instr (opRDTSCP);
ELSE
Invalid;
END;
END;
ELSIF code = 0FAEH THEN
CASE reg OF
| 5: Instr (opLFENCE);
| 6: Instr (opMFENCE);
| 7: Instr (opSFENCE);
END;
END;
END GroupModRM;
PROCEDURE Group3DNow;
BEGIN
ModRM;
CASE ORD (ReadChar ()) OF
| 00CH: Instr (opPI2FW);
| 00DH: Instr (opPI2FD);
| 01CH: Instr (opPF2IW);
| 01DH: Instr (opPF2ID);
| 08AH: Instr (opPFNACC);
| 08EH: Instr (opPFPNACC);
| 090H: Instr (opPFCMPGE);
| 094H: Instr (opPFMIN);
| 096H: Instr (opPFRCP);
| 097H: Instr (opPFRSQRT);
| 09AH: Instr (opPFSUB);
| 09EH: Instr (opPFADD);
| 0A0H: Instr (opPFCMPGT);
| 0A4H: Instr (opPFMAX);
| 0A6H: Instr (opPFRCPIT1);
| 0A7H: Instr (opPFRSQIT1);
| 0AAH: Instr (opPFSUBR);
| 0AEH: Instr (opPFACC);
| 0B0H: Instr (opPFCMPEQ);
| 0B4H: Instr (opPFMUL);
| 0B6H: Instr (opPFRCPIT1);
| 0B7H: Instr (opPMULHRW);
| 0BBH: Instr (opPSWAPD);
| 0BFH: Instr (opPAVGUSB);
ELSE
Reserved; RETURN;
END;
Pq; Qq;
END Group3DNow;
PROCEDURE Groupx87;
PROCEDURE MemInstr (instr : LONGINT);
BEGIN
Instr (instr);
AddModMem;
END MemInstr;
PROCEDURE StackInstr0i (instr : LONGINT);
BEGIN
Instr (instr);
AddFPReg (0);
AddFPReg (rm);
END StackInstr0i;
PROCEDURE StackInstri0 (instr : LONGINT);
BEGIN
Instr (instr);
AddFPReg (rm);
AddFPReg (0);
END StackInstri0;
PROCEDURE FPInstr0i (meminstr, stackinstr: LONGINT);
BEGIN
IF mod # 3 THEN
MemInstr (meminstr);
ELSE
StackInstr0i (stackinstr);
END;
END FPInstr0i;
PROCEDURE FPInstri0 (meminstr, stackinstr: LONGINT);
BEGIN
IF mod # 3 THEN
MemInstr (meminstr);
ELSE
StackInstri0 (stackinstr);
END;
END FPInstri0;
BEGIN
ModRM;
CASE code OF
0D8H:
CASE reg OF
| 0: FPInstr0i (opFADD, opFADD);
| 1: FPInstr0i (opFMUL, opFMUL);
| 2: FPInstr0i (opFCOM, opFCOM);
| 3: FPInstr0i (opFCOMP, opFCOMP);
| 4: FPInstr0i (opFSUB, opFSUB);
| 5: FPInstr0i (opFSUBR, opFSUBR);
| 6: FPInstr0i (opFDIV, opFDIV);
| 7: FPInstr0i (opFDIVR, opFDIVR);
END;
| 0D9H:
CASE reg OF
| 0: FPInstr0i (opFLD, opFLD);
| 1: IF mod # 3 THEN Invalid ELSE StackInstr0i (opFXCH) END;
| 2: IF mod # 3 THEN MemInstr (opFST) ELSIF rm = 0 THEN Instr (opFNOP) ELSE Invalid END;
| 3: IF mod # 3 THEN MemInstr (opFSTP) ELSE Reserved END;
| 4: IF mod # 3 THEN MemInstr (opFLDENV) ELSE
CASE rm OF
| 0: Instr (opFCHS);
| 1: Instr (opFABS);
| 4: Instr (opFTST);
| 5: Instr (opFXAM);
ELSE
Invalid;
END; END;
| 5: IF mod # 3 THEN MemInstr (opFLDCW) ELSE
CASE rm OF
| 0: Instr (opFLD1);
| 1: Instr (opFLDL2T);
| 2: Instr (opFLDL2E);
| 3: Instr (opFLDPI);
| 4: Instr (opFLDLG2);
| 5: Instr (opFLDLN2);
| 6: Instr (opFLDZ);
| 7: Invalid;
END; END;
| 6: IF mod # 3 THEN MemInstr (opFNSTENV) ELSE
CASE rm OF
| 0: Instr (opF2XM1);
| 1: Instr (opFYL2X);
| 2: Instr (opFPTAN);
| 3: Instr (opFPATAN);
| 4: Instr (opFXTRACT);
| 5: Instr (opFPREM1);
| 6: Instr (opFDECSTP);
| 7: Instr (opFINCSTP);
END; END;
| 7: IF mod # 3 THEN MemInstr (opFNSTCW) ELSE
CASE rm OF
| 0: Instr (opFPREM);
| 1: Instr (opFYL2XP1);
| 2: Instr (opFSQRT);
| 3: Instr (opFSINCOS);
| 4: Instr (opFRNDINT);
| 5: Instr (opFSCALE);
| 6: Instr (opFSIN);
| 7: Instr (opFCOS);
END; END;
END;
| 0DAH:
CASE reg OF
| 0: FPInstr0i (opFIADD, opFCMOVB);
| 1: FPInstr0i (opFIMUL, opFCMOVE);
| 2: FPInstr0i (opFICOM, opFCMOVBE);
| 3: FPInstr0i (opFICOMP, opFCMOVU);
| 4: IF mod # 3 THEN MemInstr (opFISUB) ELSE Invalid END;
| 5: IF mod # 3 THEN MemInstr (opFISUBR) ELSIF rm = 1 THEN Instr (opFUCOMPP) ELSE Invalid END;
| 6: IF mod # 3 THEN MemInstr (opFIDIV) ELSE Invalid END;
| 7: IF mod # 3 THEN MemInstr (opFIDIVR) ELSE Invalid END;
END;
| 0DBH:
CASE reg OF
| 0: FPInstr0i (opFILD, opFCMOVNB);
| 1: FPInstr0i (opFISTTP, opFCMOVNE);
| 2: FPInstr0i (opFIST, opFCMOVNBE);
| 3: FPInstr0i (opFISTP, opFCMOVNU);
| 4: IF mod # 3 THEN Invalid ELSE
CASE rm OF
| 2: Instr (opFNCLEX);
| 3: Instr (opFNINIT);
ELSE
Reserved;
END; END;
| 5: FPInstr0i (opFLD, opFUCOMI);
| 6: IF mod # 3 THEN Invalid ELSE StackInstr0i (opFCOMI) END;
| 7: IF mod # 3 THEN MemInstr (opFSTP) ELSE Invalid END;
END;
| 0DCH:
CASE reg OF
| 0: FPInstri0 (opFADD, opFADD);
| 1: FPInstri0 (opFMUL, opFMUL);
| 2: IF mod # 3 THEN MemInstr (opFCOM) ELSE Reserved END;
| 3: IF mod # 3 THEN MemInstr (opFCOMP) ELSE Reserved END;
| 4: FPInstri0 (opFSUB, opFSUBR);
| 5: FPInstri0 (opFSUBR, opFSUB);
| 6: FPInstri0 (opFDIV, opFDIVR);
| 7: FPInstri0 (opFDIVR, opFDIV);
END;
| 0DDH:
CASE reg OF
| 0: IF mod # 3 THEN MemInstr (opFLD) ELSE Instr (opFFREE); AddFPReg (rm) END
| 1: IF mod # 3 THEN MemInstr (opFISTTP) ELSE Reserved END;
| 2: IF mod # 3 THEN MemInstr (opFST) ELSE Instr (opFST); AddFPReg (rm) END
| 3: IF mod # 3 THEN MemInstr (opFSTP) ELSE Instr (opFSTP); AddFPReg (rm) END
| 4: FPInstri0 (opFRSTOR, opFUCOM);
| 5: IF mod # 3 THEN Invalid ELSE Instr (opFUCOMP); AddFPReg (rm) END;
| 6: IF mod # 3 THEN MemInstr (opFNSAVE) ELSE Invalid END;
| 7: IF mod # 3 THEN MemInstr (opFNSTSW) ELSE Invalid END;
END;
| 0DEH:
CASE reg OF
| 0: FPInstri0 (opFIADD, opFADDP);
| 1: FPInstri0 (opFIMUL, opFMULP);
| 2: IF mod # 3 THEN MemInstr (opFICOM) ELSE Reserved END;
| 3: IF mod # 3 THEN MemInstr (opFICOMP) ELSIF rm = 1 THEN Instr (opFCOMPP) ELSE Invalid END;
| 4: FPInstri0 (opFISUB, opFSUBRP);
| 5: FPInstri0 (opFISUBR, opFSUBP);
| 6: FPInstri0 (opFIDIV, opFDIVRP);
| 7: FPInstri0 (opFIDIVR, opFDIVP);
END;
| 0DFH:
CASE reg OF
| 0: IF mod # 3 THEN MemInstr (opFILD) ELSE Reserved END;
| 1: IF mod # 3 THEN MemInstr (opFISTTP) ELSE Reserved END;
| 2: IF mod # 3 THEN MemInstr (opFIST) ELSE Reserved END;
| 3: IF mod # 3 THEN MemInstr (opFISTP) ELSE Reserved END;
| 4: IF mod # 3 THEN MemInstr (opFBLD) ELSIF rm = 0 THEN Instr (opFNSTSW) ELSE Invalid END;
| 5: FPInstr0i (opFILD, opFUCOMIP);
| 6: FPInstr0i (opFBSTP, opFCOMIP);
| 7: IF mod # 3 THEN MemInstr (opFISTP) ELSE Invalid END;
END;
END;
END Groupx87;
BEGIN
opc := opcode(AMD64Opcode);
DecodePrefixes;
IF prFS IN opc.prefixes THEN segment := regFS
ELSIF prGS IN opc.prefixes THEN segment := regGS
ELSE segment := regNONE END;
IF byte = 00FH THEN
code := byte * 0100H + ORD (ReadChar ());
opc.hidePrefixes := TRUE;
ELSE
code := byte
END;
arg := 0;
CASE code OF
| 000H..005H: Type1 (opADD, code - 000H);
| 008H..00DH: Type1 (opOR, code - 008H);
| 010H..015H: Type1 (opADC, code - 010H);
| 018H..01DH: Type1 (opSBB, code - 018H);
| 020H..025H: Type1 (opAND, code - 020H);
| 028H..02DH: Type1 (opSUB, code - 028H);
| 030H..035H: Type1 (opXOR, code - 030H);
| 038H..03DH: Type1 (opCMP, code - 038H);
| 050H..057H: Type2 (opPUSH, (code - 050H) MOD 08H);
| 058H..05FH: Type2 (opPOP, (code - 058H) MOD 08H);
| 063H: Instr (opMOVSXD); Gv; Ed;
| 068H: Instr (opPUSH); Iz;
| 069H: Instr (opIMUL); Gv; Ev; Iz;
| 06AH: Instr (opPUSH); Ib;
| 06BH: Instr (opIMUL); Gv; Ev; Ib;
| 06CH: Instr (opINSB); Yb; DX;
| 06DH: InstrOp (opINSW, opINSD, opINSD); Yz; DX;
| 06EH: Instr (opOUTSB); DX; Xb;
| 06FH: InstrOp (opOUTSW, opOUTSD, opOUTSD); DX; Xz;
| 070H: Instr (opJO); Jb;
| 071H: Instr (opJNO); Jb;
| 072H: Instr (opJB); Jb;
| 073H: Instr (opJNB); Jb;
| 074H: Instr (opJE); Jb;
| 075H: Instr (opJNE); Jb;
| 076H: Instr (opJBE); Jb;
| 077H: Instr (opJNBE); Jb;
| 078H: Instr (opJA); Jb;
| 079H: Instr (opJS); Jb;
| 07AH: Instr (opJP); Jb;
| 07BH: Instr (opJNP); Jb;
| 07CH: Instr (opJL); Jb;
| 07DH: Instr (opJGE); Jb;
| 07EH: Instr (opJLE); Jb;
| 07FH: Instr (opJG); Jb;
| 080H..083H: Group1;
| 084H: Instr (opTEST); Eb; Gb;
| 085H: Instr (opTEST); Ev; Gv;
| 086H: Instr (opXCHG); Eb; Gb;
| 087H: Instr (opXCHG); Ev; Gv;
| 088H: Instr (opMOV); Eb; Gb;
| 089H: Instr (opMOV); Ev; Gv;
| 08AH: Instr (opMOV); Gb; Eb;
| 08BH: Instr (opMOV); Gv; Ev;
| 08CH: Instr (opMOV); Ev; Sw;
| 08DH: Instr (opLEA); Gv; M;
| 08EH: Instr (opMOV); Sw; Ev;
| 08FH: Group1a;
| 090H: IF Prefix (prF3) THEN Instr (opPAUSE) ELSE Instr (opNOP) END;
| 091H..097H: Instr (opXCHG); AddReg (GetReg (regrAX, (code - 090H) MOD 8, Prefix (prREXB))); rAX;
| 098H: InstrOp (opCBW, opCWDE, opCDQE);
| 099H: InstrOp (opCWD, opCDQ, opCQO);
| 09BH: Instr (opFWAIT);
| 09CH: InstrOp (opPUSHF, opPUSHFD, opPUSHFQ); Fv;
| 09DH: InstrOp (opPOPF, opPOPFD, opPOPFQ); Fv;
| 09EH: Instr (opSAHF);
| 09FH: Instr (opLAHF);
| 0A0H: Instr (opMOV); AL; Ob;
| 0A1H: Instr (opMOV); rAX; Ov;
| 0A2H: Instr (opMOV); Ob; AL;
| 0A3H: Instr (opMOV); Ov; rAX;
| 0A4H: Instr (opMOVSB); Yb; Xb;
| 0A5H: InstrOp (opMOVSW, opMOVSD, opMOVSQ); Yv; Xv;
| 0A6H: Instr (opCMPSB); Xb; Yb;
| 0A7H: InstrOp (opCMPSW, opCMPSD, opCMPSQ); Xv; Yv;
| 0A8H: Instr (opTEST); AL; Ib;
| 0A9H: Instr (opTEST); rAX; Iz;
| 0AAH: Instr (opSTOSB); Yb; AL;
| 0ABH: InstrOp (opSTOSW, opSTOSD, opSTOSQ); Yv; rAX;
| 0ACH: Instr (opLODSB); AL; Xb;
| 0ADH: InstrOp (opLODSW, opLODSD, opLODSQ); rAX; Xv;
| 0AEH: Instr (opSCASB); AL; Yb;
| 0AFH: InstrOp (opSCASW, opSCASD, opSCASQ); rAX; Yv;
| 0B0H..0B7H: Instr (opMOV); AddReg (GetReg (regAL, (code - 0B0H) MOD 8, Prefix (prREXB))); Ib;
| 0B8H..0BFH: Instr (opMOV); AddReg (GetReg (regrAX, (code - 0B8H) MOD 8, Prefix (prREXB))); Iv;
| 0C0H..0C1H: Group2;
| 0C2H: Instr (opRET); Iw;
| 0C3H: Instr (opRET);
| 0C6H..0C7H: Group11;
| 0C8H: Instr (opENTER); Iw; Ib;
| 0C9H: Instr (opLEAVE);
| 0CAH: Instr (opRET); Iw;
| 0CBH: Instr (opRET);
| 0CCH: Instr (opINT); AddImm (3);
| 0CDH: Instr (opINT); Ib;
| 0CFH: InstrOp (opIRET, opIRETD, opIRETQ);
| 0D0H..0D3H: Group2;
| 0D7H: Instr (opXLAT);
| 0D8H..0DFH: Groupx87;
| 0E0H: Instr (opLOOPNE); Jb;
| 0E1H: Instr (opLOOPE); Jb;
| 0E2H: Instr (opLOOP); Jb;
| 0E3H: InstrOp (opJCXZ, opJECXZ, opJRCXZ); Jb;
| 0E4H: Instr (opIN); AL; Ib;
| 0E5H: Instr (opIN); eAX; Ib;
| 0E6H: Instr (opOUT); Ib; AL;
| 0E7H: Instr (opOUT); Ib; eAX;
| 0E8H: Instr (opCALL); Jz;
| 0E9H: Instr (opJMP); Jz;
| 0EBH: Instr (opJMP); Jb;
| 0ECH: Instr (opIN); AL; DX;
| 0EDH: Instr (opIN); eAX; DX;
| 0EEH: Instr (opOUT); DX; AL;
| 0EFH: Instr (opOUT); DX; eAX;
| 0F0H: Instr (opINT); AddImm (1);
| 0F4H: Instr (opHLT);
| 0F5H: Instr (opCMC);
| 0F6H..0F7H: Group3;
| 0F8H: Instr (opCLC);
| 0F9H: Instr (opSTC);
| 0FAH: Instr (opCLI);
| 0FBH: Instr (opSTI);
| 0FCH: Instr (opCLD);
| 0FDH: Instr (opSTD);
| 0FEH: Group4;
| 0FFH: Group5;
ELSE
CASE code OF
| 00F00H: Group6;
| 00F01H: Group7;
| 00F02H: Instr (opLAR); Gv; Ew;
| 00F03H: Instr (opLSL); Gv; Ew;
| 00F05H: Instr (opSYSCALL);
| 00F06H: Instr (opCLTS);
| 00F07H: Instr (opSYSRET);
| 00F08H: Instr (opINVD);
| 00F09H: Instr (opWBINVD);
| 00F0BH: Instr (opUD2);
| 00F0DH: GroupP;
| 00F0EH: Instr (opFEMMS);
| 00F0FH: Group3DNow;
| 00F10H:
IF Prefix (prF3) THEN Instr (opMOVSS); Vdqss; Wss;
ELSIF Prefix (pr66) THEN Instr (opMOVUPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opMOVSD); Vdqsd; Wsd;
ELSE Instr (opMOVUPS); Vps; Wps; END;
| 00F11H:
IF Prefix (prF3) THEN Instr (opMOVSS); Wss; Vss;
ELSIF Prefix (pr66) THEN Instr (opMOVUPD); Wpd; Vpd;
ELSIF Prefix (prF2) THEN Instr (opMOVSD); Wsd; Vsd;
ELSE Instr (opMOVUPS); Wsd; Vsd; END;
| 00F12H:
IF Prefix (prF3) THEN Instr (opMOVSLDUP); Vps; Wps;
ELSIF Prefix (pr66) THEN Instr (opMOVLPD); Vsd; Mq;
ELSIF Prefix (prF2) THEN Instr (opMOVDDUP); Vpd; Wsd;
ELSE ModRM;
IF mod = 3 THEN Instr (opMOVHLPS); Vps; VRq;
ELSE Instr (opMOVLPS); Vps; Mq; END;
END;
| 00F13H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVLPD); Mq; Vsd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVLPS); Mq; Vps; END;
| 00F14H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opUNPCKLPD); Vpd; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opUNPCKLPS); Vps; Wq; END;
| 00F15H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opUNPCKHPD); Vpd; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opUNPCKHPS); Vps; Wq; END;
| 00F16H:
IF Prefix (prF3) THEN Instr (opMOVSHDUP); Vps; Wps;
ELSIF Prefix (pr66) THEN Instr (opMOVHPD); Vsd; Mq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE ModRM;
IF mod = 3 THEN Instr (opMOVLHPS); Vps; VRq;
ELSE Instr (opMOVHPS); Vps; Mq; END;
END;
| 00F17H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVHPD); Mq; Vsd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVHPS); Mq; Vps; END;
| 00F18H: Group16;
| 00F19H..00F1FH: Instr (opNOP); ModRM;
| 00F20H: Instr (opMOV); Rdq; Cdq;
| 00F21H: Instr (opMOV); Rdq; Ddq;
| 00F22H: Instr (opMOV); Cdq; Rdq;
| 00F23H: Instr (opMOV); Ddq; Rdq;
| 00F28H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVAPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVAPS); Vps; Wps; END;
| 00F29H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVAPD); Wpd; Vpd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVAPS); Wps; Vps; END;
| 00F2AH:
IF Prefix (prF3) THEN Instr (opCVTSI2SS); Vss; Edq;
ELSIF Prefix (pr66) THEN Instr (opCVTPI2PD); Vpd; Qq;
ELSIF Prefix (prF2) THEN Instr (opCVTSI2SD); Vsd; Edq;
ELSE Instr (opCVTPI2PS); Vps; Qq; END;
| 00F2BH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVNTPD); Mdq; Vpd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVNTPS); Mdq; Vps; END;
| 00F2CH:
IF Prefix (prF3) THEN Instr (opCVTTSS2SI); Gdq; Wss;
ELSIF Prefix (pr66) THEN Instr (opCVTTPD2PI); Pq; Wpd;
ELSIF Prefix (prF2) THEN Instr (opCVTTSD2SI); Gdq; Wsd;
ELSE Instr (opCVTTPS2PI); Pq; Wps; END;
| 00F2DH:
IF Prefix (prF3) THEN Instr (opCVTSS2SI); Gdq; Wss;
ELSIF Prefix (pr66) THEN Instr (opCVTPD2PI); Pq; Wpd;
ELSIF Prefix (prF2) THEN Instr (opCVTSD2SI); Gdq; Wsd;
ELSE Instr (opCVTPS2PI); Pq; Wps; END;
| 00F2EH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opUCOMISD); Vsd; Wsd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opUCOMISS); Vss; Wss; END;
| 00F2FH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opCOMISD); Vpd; Wsd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opCOMISS); Vps; Wps; END;
| 00F30H: Instr (opWRMSR);
| 00F31H: Instr (opRDTSC);
| 00F32H: Instr (opRDMSR);
| 00F33H: Instr (opRDPMC);
| 00F40H: Instr (opMOVO); Gv; Ev;
| 00F41H: Instr (opMOVNO); Gv; Ev;
| 00F42H: Instr (opMOVB); Gv; Ev;
| 00F43H: Instr (opMOVNB); Gv; Ev;
| 00F44H: Instr (opMOVE); Gv; Ev;
| 00F45H: Instr (opMOVNE); Gv; Ev;
| 00F46H: Instr (opMOVBE); Gv; Ev;
| 00F47H: Instr (opMOVNBE); Gv; Ev;
| 00F48H: Instr (opMOVA); Gv; Ev;
| 00F49H: Instr (opMOVS); Gv; Ev;
| 00F4AH: Instr (opMOVP); Gv; Ev;
| 00F4BH: Instr (opMOVNP); Gv; Ev;
| 00F4CH: Instr (opMOVL); Gv; Ev;
| 00F4DH: Instr (opMOVGE); Gv; Ev;
| 00F4EH: Instr (opMOVLE); Gv; Ev;
| 00F4FH: Instr (opMOVG); Gv; Ev;
| 00F50H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVMSKPD); Gd; VRpd;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVMSKPS); Gd; VRps; END;
| 00F51H:
IF Prefix (prF3) THEN Instr (opSQRTSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opSQRTPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opSQRTSD); Vsd; Wsd;
ELSE Instr (opSQRTPS); Vps; Wps; END;
| 00F52H:
IF Prefix (prF3) THEN Instr (opRSQRTSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Invalid;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opRSQRTPS); Vps; Wps; END;
| 00F53H:
IF Prefix (prF3) THEN Instr (opRCPSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Invalid;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opRCPPS); Vps; Wps; END;
| 00F54H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opANDPS); Vps; Wps;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opANDPD); Vpd; Wpd; END;
| 00F55H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opANDNPS); Vps; Wps;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opANDNPD); Vpd; Wpd; END;
| 00F56H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opORPS); Vps; Wps;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opORPD); Vpd; Wpd; END;
| 00F57H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opXORPS); Vps; Wps;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opXORPD); Vpd; Wpd; END;
| 00F58H:
IF Prefix (prF3) THEN Instr (opADDSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opADDPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opADDSD); Vsd; Wsd;
ELSE Instr (opADDPS); Vps; Wps; END;
| 00F59H:
IF Prefix (prF3) THEN Instr (opMULSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opMULPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opMULSD); Vsd; Wsd;
ELSE Instr (opMULPS); Vps; Wps; END;
| 00F5AH:
IF Prefix (prF3) THEN Instr (opCVTSS2SD); Vsd; Wss;
ELSIF Prefix (pr66) THEN Instr (opCVTPD2PS); Vps; Wpd;
ELSIF Prefix (prF2) THEN Instr (opCVTSD2SS); Vss; Wsd;
ELSE Instr (opCVTPS2PD); Vpd; Wps; END;
| 00F5BH:
IF Prefix (prF3) THEN Instr (opCVTTPS2DQ); Vdq; Wps;
ELSIF Prefix (pr66) THEN Instr (opCVTPS2DQ); Vdq; Wps;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opCVTDQ2PS); Vpd; Wdq; END;
| 00F5CH:
IF Prefix (prF3) THEN Instr (opSUBSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opSUBPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opSUBSD); Vsd; Wsd;
ELSE Instr (opSUBPS); Vps; Wps; END;
| 00F5DH:
IF Prefix (prF3) THEN Instr (opMINSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opMINPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opMINSD); Vsd; Wsd;
ELSE Instr (opMINPS); Vps; Wps; END;
| 00F5EH:
IF Prefix (prF3) THEN Instr (opDIVSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opDIVPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opDIVSD); Vsd; Wsd;
ELSE Instr (opDIVPS); Vps; Wps; END;
| 00F5FH:
IF Prefix (prF3) THEN Instr (opMAXSS); Vss; Wss;
ELSIF Prefix (pr66) THEN Instr (opMAXPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opMAXSD); Vsd; Wsd;
ELSE Instr (opMAXPS); Vps; Wps; END;
| 00F60H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPUNPCKLBW); Vdq; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPUNPCKLBW); Pq; Qd; END;
| 00F61H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPUNPCKLWD); Vdq; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPUNPCKLWD); Pq; Qd; END;
| 00F62H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPUNPCKLDQ); Vdq; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPUNPCKLDQ); Pq; Qd; END;
| 00F63H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPACKSSWB); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPACKSSWB); Pq; Qq; END;
| 00F64H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPCMPGTB); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPCMPGTB); Pq; Qq; END;
| 00F65H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPCMPGTW); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPCMPGTW); Pq; Qq; END;
| 00F66H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPCMPGTD); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPCMPGTD); Pq; Qq; END;
| 00F67H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPACKUSWB); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPACKUSWB); Pq; Qq; END;
| 00F68H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPUNPCKHBW); Vdq; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPUNPCKHBW); Pq; Qd; END;
| 00F69H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPUNPCKHWD); Vdq; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPUNPCKHWD); Pq; Qd; END;
| 00F6AH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPUNPCKHDQ); Vdq; Wq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPUNPCKHDQ); Pq; Qd; END;
| 00F6BH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPACKSSDW); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPACKSSDW); Pq; Qq; END;
| 00F6CH:
IF Prefix (pr66) THEN Instr (opPUNPCKLQDQ); Vdq; Wq;
ELSE Invalid; END;
| 00F6DH:
IF Prefix (pr66) THEN Instr (opPUNPCKHQDQ); Vdq; Wq;
ELSE Invalid; END;
| 00F6EH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVD); Vdq; Edq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVD); Pq; Edq; END;
| 00F6FH:
IF Prefix (prF3) THEN Instr (opMOVDQU); Vdq; Wdq;
ELSIF Prefix (pr66) THEN Instr (opMOVDQA); Vdq; Edq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVQ); Pq; Qq; END;
| 00F70H:
IF Prefix (prF3) THEN Instr (opPSHUFHW); Vq; Wq; Ib;
ELSIF Prefix (pr66) THEN Instr (opPSHUFD); Vdq; Wdq; Ib;
ELSIF Prefix (prF2) THEN Instr (opPSHUFLW); Vq; Wq; Ib;
ELSE Instr (opPSHUFW); Pq; Qq; Ib; END;
| 00F71H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Group12;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Group12; END;
| 00F72H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Group13;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Group13; END;
| 00F73H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Group14;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Group14; END;
| 00F74H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPCMPEQB); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPCMPEQB); Pq; Qq; END;
| 00F75H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPCMPEQW); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPCMPEQW); Pq; Qq; END;
| 00F76H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPCMPEQD); Vdq; Wdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPCMPEQD); Pq; Qq; END;
| 00F77H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Invalid;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opEMMS); END;
| 00F7CH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opHADDPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opHADDPS); Vps; Wps;
ELSE Invalid; END;
| 00F7DH:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opHSUBPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opHSUBPS); Vps; Wps;
ELSE Invalid; END;
| 00F7EH:
IF Prefix (prF3) THEN Instr (opMOVQ); Vq; Wq;
ELSIF Prefix (pr66) THEN Instr (opMOVD); Edq; Vdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVD); Edq; Pdq; END;
| 00F7FH:
IF Prefix (prF3) THEN Instr (opMOVDQU); Wdq; Vdq;
ELSIF Prefix (pr66) THEN Instr (opMOVDQA); Wdq; Vdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVQ); Qq; Pq; END;
| 00F80H: Instr (opJO); Jz;
| 00F81H: Instr (opJNO); Jz;
| 00F82H: Instr (opJB); Jz;
| 00F83H: Instr (opJNB); Jz;
| 00F84H: Instr (opJE); Jz;
| 00F85H: Instr (opJNE); Jz;
| 00F86H: Instr (opJBE); Jz;
| 00F87H: Instr (opJNBE); Jz;
| 00F88H: Instr (opJA); Jz;
| 00F89H: Instr (opJS); Jz;
| 00F8AH: Instr (opJP); Jz;
| 00F8BH: Instr (opJNP); Jz;
| 00F8CH: Instr (opJL); Jz;
| 00F8DH: Instr (opJGE); Jz;
| 00F8EH: Instr (opJLE); Jz;
| 00F8FH: Instr (opJG); Jz;
| 00F90H: Instr (opSETO); Eb;
| 00F91H: Instr (opSETNO); Eb;
| 00F92H: Instr (opSETB); Eb;
| 00F93H: Instr (opSETNB); Eb;
| 00F94H: Instr (opSETE); Eb;
| 00F95H: Instr (opSETNE); Eb;
| 00F96H: Instr (opSETBE); Eb;
| 00F97H: Instr (opSETNBE); Eb;
| 00F98H: Instr (opSETA); Eb;
| 00F99H: Instr (opSETS); Eb;
| 00F9AH: Instr (opSETP); Eb;
| 00F9BH: Instr (opSETNP); Eb;
| 00F9CH: Instr (opSETL); Eb;
| 00F9DH: Instr (opSETGE); Eb;
| 00F9EH: Instr (opSETLE); Eb;
| 00F9FH: Instr (opSETG); Eb;
| 00FA0H: Instr (opPUSH); FS;
| 00FA1H: Instr (opPOP); FS;
| 00FA2H: Instr (opCPUID);
| 00FA3H: Instr (opBT); Ev; Gv;
| 00FA4H: Instr (opSHLD); Ev; Gv; Ib;
| 00FA5H: Instr (opSHLD); Ev; Gv; CL;
| 00FA8H: Instr (opPUSH); FS;
| 00FA9H: Instr (opPOP); FS;
| 00FAAH: Instr (opRSM);
| 00FABH: Instr (opBTS); Ev; Gv;
| 00FACH: Instr (opSHRD); Ev; Gv; Ib;
| 00FADH: Instr (opSHRD); Ev; Gv; CL;
| 00FAEH: Group15;
| 00FAFH: Instr (opIMUL); Gv; Ev;
| 00FB0H: Instr (opCMPXCHG); Eb; Gb;
| 00FB1H: Instr (opCMPXCHG); Ev; Gv;
| 00FB2H: Instr (opLSS); Gz; Mp;
| 00FB3H: Instr (opBTR); Ev; Gv;
| 00FB4H: Instr (opLFS); Gz; Mp;
| 00FB5H: Instr (opLGS); Gz; Mp;
| 00FB6H: Instr (opMOVZX); Gv; Eb;
| 00FB7H: Instr (opMOVZX); Gv; Ew;
| 00FB9H: Group10;
| 00FBAH: Group8;
| 00FBBH: Instr (opBTC); Ev; Gv;
| 00FBCH: Instr (opBSF); Gv; Ev;
| 00FBDH: Instr (opBSR); Gv; Ev;
| 00FBEH: Instr (opMOVSX); Gv; Eb;
| 00FBFH: Instr (opMOVSX); Gv; Ew;
| 00FC0H: Instr (opXADD); Eb; Gb;
| 00FC1H: Instr (opXADD); Ev; Gv;
| 00FC2H:
IF Prefix (prF3) THEN Instr (opCMPSS); Vss; Wss; Ib;
ELSIF Prefix (pr66) THEN Instr (opCMPPD); Vpd; Wpd; Ib;
ELSIF Prefix (prF2) THEN Instr (opCMPSD); Vsd; Wsd; Ib;
ELSE Instr (opCMPPS); Vps; Wps; Ib; END;
| 00FC3H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Invalid;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVNTI); Mdq; Gdq; END;
| 00FC4H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPINSRW); Vdq; Ew; Ib;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPINSRW); Pq; Ew; Ib; END;
| 00FC5H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPEXTRW); Gd; VRdq; Ib;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPEXTRW); Gd; PRq; Ib; END;
| 00FC6H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opSHUFPD); Vpd; Wpd; Ib;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opSHUFPS); Vps; Wps; Ib; END;
| 00FC7H: Group9;
| 00FC8H..00FCFH: Instr (opBSWAP); AddReg (GetReg (regEAX, (code - 00FC8H) MOD 8, prREXB IN opc.prefixes)); Iv;
| 00FD0H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opADDSUBPD); Vpd; Wpd;
ELSIF Prefix (prF2) THEN Instr (opADDSUBPS); Vps; Wps;
ELSE Invalid; END;
| 00FD1H: Type3 (opPSRLW);
| 00FD2H: Type3 (opPSRLD);
| 00FD3H: Type3 (opPSRLQ);
| 00FD4H: Type3 (opPADDQ);
| 00FD5H: Type3 (opPMULLW);
| 00FD6H:
IF Prefix (prF3) THEN Instr (opMOVQ2DQ); Vdq; PRq;
ELSIF Prefix (pr66) THEN Instr (opMOVQ); Wq; Vq;
ELSIF Prefix (prF2) THEN Instr (opMOVDQ2Q); Pq; VRq;
ELSE Invalid; END;
| 00FD7H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opPMOVMSKB); Gd; VRdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opPMOVMSKB); Gd; PRq; END;
| 00FD8H: Type3 (opPSUBUSB);
| 00FD9H: Type3 (opPSUBUSW);
| 00FDAH: Type3 (opPMINUB);
| 00FDBH: Type3 (opPAND);
| 00FDCH: Type3 (opPADDUSB);
| 00FDDH: Type3 (opPADDUSW);
| 00FDEH: Type3 (opPMAXUB);
| 00FDFH: Type3 (opPANDN);
| 00FE0H: Type3 (opPAVGB);
| 00FE1H: Type3 (opPSRAW);
| 00FE2H: Type3 (opPSRAD);
| 00FE3H: Type3 (opPAVGW);
| 00FE4H: Type3 (opPMULHUW);
| 00FE5H: Type3 (opPMULHW);
| 00FE6H:
IF Prefix (prF3) THEN Instr (opCVTDQ2PD); Vpd; Wq;
ELSIF Prefix (pr66) THEN Instr (opCVTTPD2DQ); Vq; Wpd;
ELSIF Prefix (prF2) THEN Instr (opPSADBW); Pq; Qq;
ELSE Invalid; END;
| 00FE7H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMOVNTDQ); Mdq; Vdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMOVNTQ); Mq; Pq; END;
| 00FE8H: Type3 (opPSUBSB);
| 00FE9H: Type3 (opPSUBSW);
| 00FEAH: Type3 (opPMINSW);
| 00FEBH: Type3 (opPOR);
| 00FECH: Type3 (opPADDSB);
| 00FEDH: Type3 (opPADDSW);
| 00FEEH: Type3 (opPMAXSW);
| 00FEFH: Type3 (opPXOR);
| 00FF0H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Invalid;
ELSIF Prefix (prF2) THEN Instr (opLDDQU); Vpd; Mdq;
ELSE Invalid; END;
| 00FF1H: Type3 (opPSLLW);
| 00FF2H: Type3 (opPSLLD);
| 00FF3H: Type3 (opPSLLQ);
| 00FF4H: Type3 (opPMULUDQ);
| 00FF5H: Type3 (opPMADDWD);
| 00FF6H: Type3 (opPSADBW);
| 00FF7H:
IF Prefix (prF3) THEN Invalid;
ELSIF Prefix (pr66) THEN Instr (opMASKMOVDQU); Vdq; VRdq;
ELSIF Prefix (prF2) THEN Invalid;
ELSE Instr (opMASKMOVQ); Pq; PRq; END;
| 00FF8H: Type3 (opPSUBB);
| 00FF9H: Type3 (opPSUBW);
| 00FFAH: Type3 (opPSUBD);
| 00FFBH: Type3 (opPSUBQ);
| 00FFCH: Type3 (opPADDB);
| 00FFDH: Type3 (opPADDW);
| 00FFEH: Type3 (opPADDD);
ELSE
Invalid;
END;
END;
WHILE arg < maxArgs DO
opc.arg[arg] := NIL; INC (arg);
END
END DecodeThis;
END AMD64Decoder;
PROCEDURE PrintReg (w : Streams.Writer; reg : LONGINT);
BEGIN
CASE reg OF
| regAL: w.String ("AL");
| regCL: w.String ("CL");
| regDL: w.String ("DL");
| regBL: w.String ("BL");
| regAH: w.String ("AH");
| regCH: w.String ("CH");
| regDH: w.String ("DH");
| regBH: w.String ("BH");
| regSPL: w.String ("SPL");
| regBPL: w.String ("BPL");
| regSIL: w.String ("SIL");
| regDIL: w.String ("DIL");
| regR8B: w.String ("R8B");
| regR9B: w.String ("R9B");
| regR10B: w.String ("R10B");
| regR11B: w.String ("R11B");
| regR12B: w.String ("R12B");
| regR13B: w.String ("R13B");
| regR14B: w.String ("R14B");
| regR15B: w.String ("R15B");
| regAX: w.String ("AX");
| regCX: w.String ("CX");
| regDX: w.String ("DX");
| regBX: w.String ("BX");
| regSP: w.String ("SP");
| regBP: w.String ("BP");
| regSI: w.String ("SI");
| regDI: w.String ("DI");
| regR8W: w.String ("R8W");
| regR9W: w.String ("R9W");
| regR10W: w.String ("R10W");
| regR11W: w.String ("R11W");
| regR12W: w.String ("R12W");
| regR13W: w.String ("R13W");
| regR14W: w.String ("R14W");
| regR15W: w.String ("R15W");
| regEAX: w.String ("EAX");
| regECX: w.String ("ECX");
| regEDX: w.String ("EDX");
| regEBX: w.String ("EBX");
| regESP: w.String ("ESP");
| regEBP: w.String ("EBP");
| regESI: w.String ("ESI");
| regEDI: w.String ("EDI");
| regR8D: w.String ("R8D");
| regR9D: w.String ("R9D");
| regR10D: w.String ("R10D");
| regR11D: w.String ("R11D");
| regR12D: w.String ("R12D");
| regR13D: w.String ("R13D");
| regR14D: w.String ("R14D");
| regR15D: w.String ("R15D");
| regRAX: w.String ("RAX");
| regRCX: w.String ("RCX");
| regRDX: w.String ("RDX");
| regRBX: w.String ("RBX");
| regRSP: w.String ("RSP");
| regRBP: w.String ("RBP");
| regRSI: w.String ("RSI");
| regRDI: w.String ("RDI");
| regR8: w.String ("R8");
| regR9: w.String ("R9");
| regR10: w.String ("R10");
| regR11: w.String ("R11");
| regR12: w.String ("R12");
| regR13: w.String ("R13");
| regR14: w.String ("R14");
| regR15: w.String ("R15");
| regES: w.String ("ES");
| regCS: w.String ("CS");
| regSS: w.String ("SS");
| regDS: w.String ("DS");
| regFS: w.String ("FS");
| regGS: w.String ("GS");
| regST0: w.String ("ST0");
| regST1: w.String ("ST1");
| regST2: w.String ("ST2");
| regST3: w.String ("ST3");
| regST4: w.String ("ST4");
| regST5: w.String ("ST5");
| regST6: w.String ("ST6");
| regST7: w.String ("ST7");
| regCR0: w.String ("CR0");
| regCR1: w.String ("CR1");
| regCR2: w.String ("CR2");
| regCR3: w.String ("CR3");
| regCR4: w.String ("CR4");
| regCR5: w.String ("CR5");
| regCR6: w.String ("CR6");
| regCR7: w.String ("CR7");
| regCR8: w.String ("CR8");
| regCR9: w.String ("CR9");
| regCR10: w.String ("CR10");
| regCR11: w.String ("CR11");
| regCR12: w.String ("CR12");
| regCR13: w.String ("CR13");
| regCR14: w.String ("CR14");
| regDR0: w.String ("DR0");
| regDR1: w.String ("DR1");
| regDR2: w.String ("DR2");
| regDR3: w.String ("DR3");
| regDR4: w.String ("DR4");
| regDR5: w.String ("DR5");
| regDR6: w.String ("DR6");
| regDR7: w.String ("DR7");
| regDR8: w.String ("DR8");
| regDR9: w.String ("DR9");
| regDR10: w.String ("DR10");
| regDR11: w.String ("DR11");
| regDR12: w.String ("DR12");
| regDR13: w.String ("DR13");
| regDR14: w.String ("DR14");
| regXMM0: w.String ("XMM0");
| regXMM1: w.String ("XMM1");
| regXMM2: w.String ("XMM2");
| regXMM3: w.String ("XMM3");
| regXMM4: w.String ("XMM4");
| regXMM5: w.String ("XMM5");
| regXMM6: w.String ("XMM6");
| regXMM7: w.String ("XMM7");
| regXMM8: w.String ("XMM8");
| regXMM9: w.String ("XMM9");
| regXMM10: w.String ("XMM10");
| regXMM11: w.String ("XMM11");
| regXMM12: w.String ("XMM12");
| regXMM13: w.String ("XMM13");
| regXMM14: w.String ("XMM14");
| regMMX0: w.String ("MMX0");
| regMMX1: w.String ("MMX1");
| regMMX2: w.String ("MMX2");
| regMMX3: w.String ("MMX3");
| regMMX4: w.String ("MMX4");
| regMMX5: w.String ("MMX5");
| regMMX6: w.String ("MMX6");
| regMMX7: w.String ("MMX7");
| regIP: w.String ("IP");
| regRIP: w.String ("RIP");
END
END PrintReg;
PROCEDURE PrintImm (n: HUGEINT; w : Streams.Writer);
VAR high, low: LONGINT;
BEGIN
IF (n >= -80H) & (n < 100H) THEN
w.Int (SYSTEM.VAL (SHORTINT, n), 0);
ELSE
SYSTEM.GET (SYSTEM.ADR (n), low);
SYSTEM.GET (SYSTEM.ADR (n) + 4, high);
IF high # 0 THEN w.Hex (high, 0) END;
w.Hex (low, 0); w.Char ('H');
END;
END PrintImm;
PROCEDURE AMD64DecoderFactory (reader : Streams.Reader) : Decoder.Decoder;
VAR
amd64Decoder : AMD64Decoder;
BEGIN
NEW(amd64Decoder, reader);
RETURN amd64Decoder
END AMD64DecoderFactory;
PROCEDURE Init*;
BEGIN
Decoder.RegisterDecoder(objFileSuffix, AMD64DecoderFactory, NIL);
END Init;
END AMD64Decoder.
SystemTools.Free AMD64Decoder~
AMD64Decoder.Init~
Decoder.Open Test.Abx~
SystemTools.Free Decoder~
Decoder.Open Test.Bbx~