MODULE FoxAMD64InstructionSet; (** AUTHOR "fof & fn"; PURPOSE "Oberon Compiler:AMD 64 Instruction Set"; **) (* (c) fof ETH Zürich, 2008 *) (** This module has been written with inspiration from -module CCIx86A.Mod : Component Compiler, Intel x86 Backend Assembler, 2005-2007, by Luc Bläser and -module AsmAMD64.Mod: AMD64 instruction set repository, 2006, by Florian Negele The instruction set reference generator is built by parsing the file InstructionSetAMD64.txt also written by Florian Negele Parser for parsing the file is contained in FoxProgTools.Mod **) (** referenced literature [AMD:3] AMD64 Architecture Programmer's Manual Volume 3:General-Purpose and System Instructions Revision 3.14 September 2007 [AMD:4] AMD64 Architecture Programmer's Manual Volume 4: 128-Bit Media Instructions Revision 3.14 September 2007 [AMD:5] AMD64 Architecture Programmer's Manual Volume 5: 64-Bit Media and x87 Floating-Point Instructions Revision 3.14 September 2007 [AMD:SSE5] AMD64 Technology 128-Bit SSE5 Instruction Set Revision 3.01 August 2007 [INTEL:2A] Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M September 2008 [INTEL:2B] Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z September 2008 **) IMPORT KernelLog (* debugging *); CONST maxCPUs* = 30; maxNumberOperands*=5; (* maximal two source and one destination operand *) (* numbers generated by the instruction set parser *) maxNumberMnemonics = 1012; maxNumberInstructions = 3380; maxMnemonicNameLength =20; maxCodeLength* =12; none* = -1; bitsDefault*=0; bits8*=1; bits16*=2; bits32*=4; bits64*=8; bits128*=16; (** cpu options **) cpu8086* = 0; cpu186* = 1; cpu286* = 2; cpu386* = 3; cpu486* = 4; cpuPentium* = 5; cpuP6* = 6; cpuKatmai* = 7; cpuWillamette* = 8; cpuPrescott* = 9; cpuAMD64* = 10; (* unused options cpuSW = 11; cpuSB = 11; cpuSMM = 11; cpuAR1 = 11; cpuAR2 = 11; cpuND = 11; *) (** options selectable with CODE {SYSTEM.....} **) cpuPrivileged* = 20; cpuProtected* = 21; cpuSSE* = 22; cpuSSE2* = 23; cpuSSE3* = 24; cpu3DNow* = 25; cpuMMX* = 26; cpuFPU* = 27; cpuOptions* = {cpuPrivileged .. cpuFPU}; (** instruction options **) optO16* = 0; (* default 16bit operand size *) optO32* = 1; (* default 32bit operand size *) optO64* = 2; (* default 64bit operand size *) optD64* = 3; (* default 64bit operand size in 64bit mode *) optNot64* = 4; (* instruction invalid in 64bit mode *) optA16* = 5; (* default 16bit address size *) optA32* = 6; (* default 32bit address size *) optPOP* = 7; (* an operand size override prefix must preceed the instruction *) optPLOCK* = 8; (* a lock prefix must preceed the instruction *) optPREP* = 9; (* a repeat prefix must preceed the instruction *) optPREPN* = 10; (* a repeat prefix must preceed the instruction *) (* FoxProgTools.Enum -l=1 -e (** operand types, numbers assigned to the types do not have a special meaning **) (* register classes first *) reg8 reg16 reg32 reg64 CRn DRn segReg mmx xmm ymm sti (* other classes *) mem imm ioffset pntr1616 pntr1632 (* special registers *) AL AX CL CR8 CS DS DX EAX ECX ES FS GS RAX SS rAX st0 (* immediates and memory locations *) imm16 imm32 imm64 imm8 uimm16 uimm32 uimm8 simm16 simm32 simm8 mem256 mem128 mem16 mem32 mem64 mem8 moffset16 moffset32 moffset64 moffset8 rel16off rel32off rel8off (* ambivalent operand types *) reg3264 regmem16 regmem32 regmem64 regmem8 reg32mem16 mmxmem32 mmxmem64 xmmmem256 xmmmem128 xmmmem32 xmmmem64 xmmmem8 xmmmem16 ymmmem128 ymmmem256 (* miscellaneous *) one three vm32x vm32y vm64x vm64y m2z; ~ *) (** operand types, numbers assigned to the types do not have a special meaning **) (* register classes first *) reg8*= 0; reg16*= 1; reg32*= 2; reg64*= 3; CRn*= 4; DRn*= 5; segReg*= 6; mmx*= 7; xmm*= 8; ymm*= 9; sti*= 10; (* other classes *) mem*= 11; imm*= 12; ioffset*= 13; pntr1616*= 14; pntr1632*= 15; (* special registers *) AL*= 16; AX*= 17; CL*= 18; CR8*= 19; CS*= 20; DS*= 21; DX*= 22; EAX*= 23; ECX*= 24; ES*= 25; FS*= 26; GS*= 27; RAX*= 28; SS*= 29; rAX*= 30; st0*= 31; (* immediates and memory locations *) imm16*= 32; imm32*= 33; imm64*= 34; imm8*= 35; uimm16*= 36; uimm32*= 37; uimm8*= 38; simm16*= 39; simm32*= 40; simm8*= 41; mem256*= 42; mem128*= 43; mem16*= 44; mem32*= 45; mem64*= 46; mem8*= 47; moffset16*= 48; moffset32*= 49; moffset64*= 50; moffset8*= 51; rel16off*= 52; rel32off*= 53; rel8off*= 54; (* ambivalent operand types *) reg3264*= 55; regmem16*= 56; regmem32*= 57; regmem64*= 58; regmem8*= 59; reg32mem16*= 60; mmxmem32*= 61; mmxmem64*= 62; xmmmem256*= 63; xmmmem128*= 64; xmmmem32*= 65; xmmmem64*= 66; xmmmem8*= 67; xmmmem16*= 68; ymmmem128*= 69; ymmmem256*= 70; (* miscellaneous *) one*= 71; three*= 72; vm32x*= 73; vm32y*= 74; vm64x*= 75; vm64y*= 76; m2z*= 77; (** prefixes **) prfOP* = 066H; prfADR* = 067H; prfCS* = 02EH; (* ignored in 64bit mode *) prfDS* = 03EH; (* ignored in 64bit mode *) prfES* = 026H; (* ignored in 64bit mode *) prfFS* = 064H; prfGS* = 065H; prfSS* = 036H; (* ignored in 64bit mode *) prfLOCK* = 0F0H; prfREP* = 0F3H; prfREPE* = 0F3H; prfREPZ* = 0F3H; prfREPNE* = 0F2H; prfREPNZ* = 0F2H; (* registers FoxProgTools.Enum -e -l=8 -s=0 (** 8 bit general purpose registers **) regAL regCL regDL regBL regAH regCH regDH regBH regSPL regBPL regSIL regDIL ~ FoxProgTools.Enum -e -l=16 -s=16 regR8B regR9B regR10B regR11B regR12B regR13B regR14B regR15B ~ FoxProgTools.Enum -l=8 -e -s=32 (** 16 bit general purpose registers **) regAX regCX regDX regBX regSP regBP regSI regDI regR8W regR9W regR10W regR11W regR12W regR13W regR14W regR15W ~ FoxProgTools.Enum -l=8 -e -s=64 (** 32 bit general purpose registers **) regEAX regECX regEDX regEBX regESP regEBP regESI regEDI regR8D regR9D regR10D regR11D regR12D regR13D regR14D regR15D ~ FoxProgTools.Enum -l=8 -e -s=96 (** 64 bit general purpose registers **) regRAX regRCX regRDX regRBX regRSP regRBP regRSI regRDI regR8 regR9 regR10 regR11 regR12 regR13 regR14 regR15 regRIP ~ FoxProgTools.Enum -l=8 -e -s=128 regES regCS regSS regDS regFS regGS regCR0 regCR1 regCR2 regCR3 regCR4 regCR5 regCR6 regCR7 regCR8 regCR9 regCR10 regCR11 regCR12 regCR13 regCR14 regCR15 regDR0 regDR1 regDR2 regDR3 regDR4 regDR5 regDR6 regDR7 regDR8 regDR9 regDR10 regDR11 regDR12 regDR13 regDR14 regDR15 regST0 regST1 regST2 regST3 regST4 regST5 regST6 regST7 regXMM0 regXMM1 regXMM2 regXMM3 regXMM4 regXMM5 regXMM6 regXMM7 regXMM8 regXMM9 regXMM10 regXMM11 regXMM12 regXMM13 regXMM14 regXMM15 regMMX0 regMMX1 regMMX2 regMMX3 regMMX4 regMMX5 regMMX6 regMMX7 regYMM0 regYMM1 regYMM2 regYMM3 regYMM4 regYMM5 regYMM6 regYMM7 regYMM8 regYMM9 regYMM10 regYMM11 regYMM12 regYMM13 regYMM14 regYMM15 numberRegisters ~ *) (* regNumber = S*32 + N N\S 0 1 2 3 0 AL AX EAX RAX 1 CL CX ECX RCX 2 DL DX EDX RDX 3 BL BX EBX RBX 4 SPL SP ESP RSP 5 BPL BP EBP RBP 6 SIL SI ESI RSI 7 DIL DI EDI RDI 8 R8B R8W R8D R8 9 R9B R9W R9D R9 10 R10B R10W R10D R10 11 R11B R11W R11D R11 12 R12B R12W R12D R12 13 R13B R13W R13D R13 14 R14B R14W R14D R14 15 R15B R15W R15D R15 16 AH 17 CH 18 BH 19 DH *) (** register indices, the order is arbitrary and has no meaning for instruction encoding, it nevertheless should not be changed as the numbers are important on in the code generator ! **) (** 8 bit general purpose registers : index DIV 32 = 0**) regAL*= 0; regCL*= 1; regDL*= 2; regBL*= 3; regSPL*= 4; regBPL*= 5; regSIL*= 6; regDIL*= 7; regAH*= 16; regCH*= 17; regDH*= 18; regBH*= 19; regR8B*= 8; regR9B*= 9; regR10B*= 10; regR11B*= 11; regR12B*= 12; regR13B*= 13; regR14B*= 14; regR15B*= 15; (** 16 bit general purpose registers : index DIV 32 = 1**) regAX*= 32; regCX*= 33; regDX*= 34; regBX*= 35; regSP*= 36; regBP*= 37; regSI*= 38; regDI*= 39; regR8W*= 40; regR9W*= 41; regR10W*= 42; regR11W*= 43; regR12W*= 44; regR13W*= 45; regR14W*= 46; regR15W*= 47; (** 32 bit general purpose registers: index DIV 32 = 2 **) regEAX*= 64; regECX*= 65; regEDX*= 66; regEBX*= 67; regESP*= 68; regEBP*= 69; regESI*= 70; regEDI*= 71; regR8D*= 72; regR9D*= 73; regR10D*= 74; regR11D*= 75; regR12D*= 76; regR13D*= 77; regR14D*= 78; regR15D*= 79; (** 64 bit general purpose registers : index DIV 32 = 3 (except for regRIP) **) regRAX*= 96; regRCX*= 97; regRDX*= 98; regRBX*= 99; regRSP*= 100; regRBP*= 101; regRSI*= 102; regRDI*= 103; regR8*= 104; regR9*= 105; regR10*= 106; regR11*= 107; regR12*= 108; regR13*= 109; regR14*= 110; regR15*= 111; regRIP*= 112; (** other registers **) regES*= 128; regCS*= 129; regSS*= 130; regDS*= 131; regFS*= 132; regGS*= 133; regCR0*= 134; regCR1*= 135; regCR2*= 136; regCR3*= 137; regCR4*= 138; regCR5*= 139; regCR6*= 140; regCR7*= 141; regCR8*= 142; regCR9*= 143; regCR10*= 144; regCR11*= 145; regCR12*= 146; regCR13*= 147; regCR14*= 148; regCR15*= 149; regDR0*= 150; regDR1*= 151; regDR2*= 152; regDR3*= 153; regDR4*= 154; regDR5*= 155; regDR6*= 156; regDR7*= 157; regDR8*= 158; regDR9*= 159; regDR10*= 160; regDR11*= 161; regDR12*= 162; regDR13*= 163; regDR14*= 164; regDR15*= 165; regST0*= 166; regST1*= 167; regST2*= 168; regST3*= 169; regST4*= 170; regST5*= 171; regST6*= 172; regST7*= 173; regXMM0*= 174; regXMM1*= 175; regXMM2*= 176; regXMM3*= 177; regXMM4*= 178; regXMM5*= 179; regXMM6*= 180; regXMM7*= 181; regXMM8*= 182; regXMM9*= 183; regXMM10*= 184; regXMM11*= 185; regXMM12*= 186; regXMM13*= 187; regXMM14*= 188; regXMM15*= 189; regMMX0*= 190; regMMX1*= 191; regMMX2*= 192; regMMX3*= 193; regMMX4*= 194; regMMX5*= 195; regMMX6*= 196; regMMX7*= 197; regYMM0*= 198; regYMM1*= 199; regYMM2*= 200; regYMM3*= 201; regYMM4*= 202; regYMM5*= 203; regYMM6*= 204; regYMM7*= 205; regYMM8*= 206; regYMM9*= 207; regYMM10*= 208; regYMM11*= 209; regYMM12*= 210; regYMM13*= 211; regYMM14*= 212; regYMM15*= 213; numberRegisters*= 214; VAR opAAA*, opAAD*, opAAM*, opAAS*, opADC*, opADD*, opADDPD*, opADDPS*, opADDSD*, opADDSS*, opADDSUBPD*, opADDSUBPS*, opAND*, opANDNPD*, opANDNPS*, opANDPD*, opANDPS*, opARPL*, opBOUND*, opBSF*, opBSR*, opBSWAP*, opBT*, opBTC*, opBTR*, opBTS*, opCALL*, opCALLFAR*, opCBW*, opCDQ*, opCDQE*, opCLC*, opCLD*, opCLFLUSH*, opCLGI*, opCLI*, opCLTS*, opCMC*, opCMOVA*, opCMOVAE*, opCMOVB*, opCMOVBE*, opCMOVC*, opCMOVE*, opCMOVG*, opCMOVGE*, opCMOVL*, opCMOVLE*, opCMOVNA*, opCMOVNAE*, opCMOVNB*, opCMOVNBE*, opCMOVNC*, opCMOVNE*, opCMOVNG*, opCMOVNGE*, opCMOVNL*, opCMOVNLE*, opCMOVNO*, opCMOVNP*, opCMOVNS*, opCMOVNZ*, opCMOVO*, opCMOVP*, opCMOVPE*, opCMOVPO*, opCMOVS*, opCMOVZ*, opCMP*, opCMPPD*, opCMPPS*, opCMPS*, opCMPSB*, opCMPSD*, opCMPSQ*, opCMPSS*, opCMPSW*, opCMPXCHG*, opCMPXCHG16B*, opCMPXCHG8B*, opCOMISD*, opCOMISS*, opCPUID*, opCQO*, opCVTDQ2PD*, opCVTDQ2PS*, opCVTPD2DQ*, opCVTPD2PI*, opCVTPD2PS*, opCVTPI2PD*, opCVTPI2PS*, opCVTPS2DQ*, opCVTPS2PD*, opCVTPS2PI*, opCVTSD2SI*, opCVTSD2SS*, opCVTSI2SD*, opCVTSI2SS*, opCVTSS2SD*, opCVTSS2SI*, opCVTTPD2DQ*, opCVTTPD2PI*, opCVTTPS2DQ*, opCVTTPS2PI*, opCVTTSD2SI*, opCVTTSS2SI*, opCWD*, opCWDE*, opDAA*, opDAS*, opDEC*, opDIV*, opDIVPD*, opDIVPS*, opDIVSD*, opDIVSS*, opEMMS*, opENTER*, opF2XM1*, opFABS*, opFADD*, opFADDP*, opFBLD*, opFBSTP*, opFCHS*, opFCLEX*, opFCMOVB*, opFCMOVBE*, opFCMOVE*, opFCMOVNB*, opFCMOVNBE*, opFCMOVNE*, opFCMOVNU*, opFCMOVU*, opFCOM*, opFCOMI*, opFCOMIP*, opFCOMP*, opFCOMPP*, opFCOS*, opFDECSTP*, opFDIV*, opFDIVP*, opFDIVR*, opFDIVRP*, opFEMMS*, opFFREE*, opFIADD*, opFICOM*, opFICOMP*, opFIDIV*, opFIDIVR*, opFILD*, opFIMUL*, opFINCSTP*, opFINIT*, opFIST*, opFISTP*, opFISTTP*, opFISUB*, opFISUBR*, opFLD*, opFLD1*, opFLDCW*, opFLDENV*, opFLDL2E*, opFLDL2T*, opFLDLG2*, opFLDLN2*, opFLDPI*, opFLDZ*, opFMUL*, opFMULP*, opFNCLEX*, opFNINIT*, opFNOP*, opFNSAVE*, opFNSTCW*, opFNSTENV*, opFNSTSW*, opFPATAN*, opFPREM*, opFPREM1*, opFPTAN*, opFRNDINT*, opFRSTOR*, opFSAVE*, opFSCALE*, opFSIN*, opFSINCOS*, opFSQRT*, opFST*, opFSTCW*, opFSTENV*, opFSTP*, opFSTSW*, opFSUB*, opFSUBP*, opFSUBR*, opFSUBRP*, opFTST*, opFUCOM*, opFUCOMI*, opFUCOMIP*, opFUCOMP*, opFUCOMPP*, opFWAIT*, opFXAM*, opFXCH*, opFXRSTOR*, opFXSAVE*, opFXTRACT*, opFYL2X*, opFYL2XP1*, opHADDPD*, opHADDPS*, opHLT*, opHSUBPD*, opHSUBPS*, opIDIV*, opIMUL*, opIN*, opINC*, opINS*, opINSB*, opINSD*, opINSW*, opINT*, opINT3*, opINTO*, opINVD*, opINVLPG*, opINVLPGA*, opIRET*, opIRETD*, opIRETQ*, opJA*, opJAE*, opJB*, opJBE*, opJC*, opJCXZ*, opJE*, opJECXZ*, opJG*, opJGE*, opJL*, opJLE*, opJMP*, opJMPFAR*, opJNA*, opJNAE*, opJNB*, opJNBE*, opJNC*, opJNE*, opJNG*, opJNGE*, opJNL*, opJNLE*, opJNO*, opJNP*, opJNS*, opJNZ*, opJO*, opJP*, opJPE*, opJPO*, opJRCXZ*, opJS*, opJZ*, opLAHF*, opLAR*, opLDDQU*, opLDMXCSR*, opLDS*, opLEA*, opLEAVE*, opLES*, opLFENCE*, opLFS*, opLGDT*, opLGS*, opLIDT*, opLLDT*, opLMSW*, opLODS*, opLODSB*, opLODSD*, opLODSQ*, opLODSW*, opLOOP*, opLOOPE*, opLOOPNE*, opLOOPNZ*, opLOOPZ*, opLSL*, opLSS*, opLTR*, opMASKMOVDQU*, opMASKMOVQ*, opMAXPD*, opMAXPS*, opMAXSD*, opMAXSS*, opMFENCE*, opMINPD*, opMINPS*, opMINSD*, opMINSS*, opMOV*, opMOVAPD*, opMOVAPS*, opMOVD*, opMOVDDUP*, opMOVDQ2Q*, opMOVDQA*, opMOVDQU*, opMOVHLPS*, opMOVHPD*, opMOVHPS*, opMOVLHPS*, opMOVLPD*, opMOVLPS*, opMOVMSKPD*, opMOVMSKPS*, opMOVNTDQ*, opMOVNTI*, opMOVNTPD*, opMOVNTPS*, opMOVNTQ*, opMOVQ*, opMOVQ2DQ*, opMOVS*, opMOVSB*, opMOVSD*, opMOVSHDUP*, opMOVSLDUP*, opMOVSQ*, opMOVSS*, opMOVSW*, opMOVSX*, opMOVSXD*, opMOVUPD*, opMOVUPS*, opMOVZX*, opMUL*, opMULPD*, opMULPS*, opMULSD*, opMULSS*, opNEG*, opNOP*, opNOT*, opOR*, opORPD*, opORPS*, opOUT*, opOUTS*, opOUTSB*, opOUTSD*, opOUTSW*, opPACKSSDW*, opPACKSSWB*, opPACKUSWB*, opPADDB*, opPADDD*, opPADDQ*, opPADDSB*, opPADDSW*, opPADDUSB*, opPADDUSW*, opPADDW*, opPAND*, opPANDN*, opPAUSE*, opPAVGB*, opPAVGUSB*, opPAVGW*, opPCMPEQB*, opPCMPEQD*, opPCMPEQW*, opPCMPGTB*, opPCMPGTD*, opPCMPGTW*, opPEXTRW*, opPF2ID*, opPF2IW*, opPFACC*, opPFADD*, opPFCMPEQ*, opPFCMPGE*, opPFCMPGT*, opPFMAX*, opPFMIN*, opPFMUL*, opPFNACC*, opPFPNACC*, opPFRCP*, opPFRCPIT1*, opPFRCPIT2*, opPFRSQIT1*, opPFRSQRT*, opPFSUB*, opPFSUBR*, opPI2FD*, opPI2FW*, opPINSRW*, opPMADDWD*, opPMAXSW*, opPMAXUB*, opPMINSW*, opPMINUB*, opPMOVMSKB*, opPMULHRW*, opPMULHUW*, opPMULHW*, opPMULLW*, opPMULUDQ*, opPOP*, opPOPA*, opPOPAD*, opPOPAW*, opPOPF*, opPOPFD*, opPOPFQ*, opPOR*, opPREFETCH*, opPREFETCHNTA*, opPREFETCHT0*, opPREFETCHT1*, opPREFETCHT2*, opPREFETCHW*, opPSADBW*, opPSHUFD*, opPSHUFHW*, opPSHUFLW*, opPSHUFW*, opPSLLD*, opPSLLDQ*, opPSLLQ*, opPSLLW*, opPSRAD*, opPSRAW*, opPSRLD*, opPSRLDQ*, opPSRLQ*, opPSRLW*, opPSUBB*, opPSUBD*, opPSUBQ*, opPSUBSB*, opPSUBSW*, opPSUBUSB*, opPSUBUSW*, opPSUBW*, opPSWAPD*, opPUNPCKHBW*, opPUNPCKHDQ*, opPUNPCKHQDQ*, opPUNPCKHWD*, opPUNPCKLBW*, opPUNPCKLDQ*, opPUNPCKLQDQ*, opPUNPCKLWD*, opPUSH*, opPUSHA*, opPUSHAD*, opPUSHF*, opPUSHFD*, opPUSHFQ*, opPXOR*, opRCL*, opRCPPS*, opRCPSS*, opRCR*, opRDMSR*, opRDPMC*, opRDTSC*, opRDTSCP*, opRET*, opRETF*, opROL*, opROR*, opRSM*, opRSQRTPS*, opRSQRTSS*, opSAHF*, opSAL*, opSAR*, opSBB*, opSCAS*, opSCASB*, opSCASD*, opSCASQ*, opSCASW*, opSETA*, opSETAE*, opSETB*, opSETBE*, opSETC*, opSETE*, opSETG*, opSETGE*, opSETL*, opSETLE*, opSETNA*, opSETNAE*, opSETNB*, opSETNBE*, opSETNC*, opSETNE*, opSETNG*, opSETNGE*, opSETNL*, opSETNLE*, opSETNO*, opSETNP*, opSETNS*, opSETNZ*, opSETO*, opSETP*, opSETPE*, opSETPO*, opSETS*, opSETZ*, opSFENCE*, opSGDT*, opSHL*, opSHLD*, opSHR*, opSHRD*, opSHUFPD*, opSHUFPS*, opSIDT*, opSKINIT*, opSLDT*, opSMSW*, opSQRTPD*, opSQRTPS*, opSQRTSD*, opSQRTSS*, opSTC*, opSTD*, opSTGI*, opSTI*, opSTMXCSR*, opSTOS*, opSTOSB*, opSTOSD*, opSTOSQ*, opSTOSW*, opSTR*, opSUB*, opSUBPD*, opSUBPS*, opSUBSD*, opSUBSS*, opSWAPGS*, opSYSCALL*, opSYSENTER*, opSYSEXIT*, opSYSRET*, opTEST*, opUCOMISD*, opUCOMISS*, opUD2*, opUNPCKHPD*, opUNPCKHPS*, opUNPCKLPD*, opUNPCKLPS*, opVERR*, opVERW*, opVMLOAD*, opVMMCALL*, opVMRUN*, opVMSAVE*, opWBINVD*, opWRMSR*, opXADD*, opXCHG*, opXLAT*, opXLATB*, opXOR*, opXORPD*, opXORPS*: LONGINT; (* AVX 2 Media instructions *) opVAESKEYGENASSIST*, opVPMADCSWD*, opVADDPD*, opVADDPS*, opVADDSD*, opVADDSS*, opVADDSUBPD*, opVADDSUBPS*, opVAESDEC*, opVAESDECLAST*, opVAESENC*, opVAESENCLAST*, opVAESIMC*, opVANDNPD*, opVANDNPS*, opVANDPD*, opVANDPS*, opVBLENDPD*, opVBLENDPS*, opVBLENDVPD*, opVBLENDVPS*, opVBROADCASTF128*, opVBROADCASTI128*, opVBROADCASTSD*, opVBROADCASTSS*, opVCMPPD*, opVCMPPS*, opVCMPSD*, opVCMPSS*, opVCOMISD*, opVCOMISS*, opVCVTDQ2PD*, opVCVTDQ2PS*, opVCVTPD2DQ*, opVCVTPD2PS*, opVCVTPH2PS*, opVCVTPS2DQ*, opVCVTPS2PD*, opVCVTPS2PH*, opVCVTSD2SI*, opVCVTSD2SS*, opVCVTSI2SD*, opVCVTSI2SS*, opVCVTSS2SD*, opVCVTSS2SI*, opVCVTTPD2DQ*, opVCVTTPS2DQ*, opVCVTTSD2SI*, opVCVTTSS2SI*, opVDIVPD*, opVDIVPS*, opVDIVSD*, opVDIVSS*, opVDPPD*, opVDPPS*, opVEXTRACTF128*, opVEXTRACTI128*, opVEXTRACTPS*, opVFMADD132PD*, opVFMADD132PS*, opVFMADD132SD*, opVFMADD132SS*, opVFMADD213PD*, opVFMADD213PS*, opVFMADD213SD*, opVFMADD213SS*, opVFMADD231PD*, opVFMADD231PS*, opVFMADD231SD*, opVFMADD231SS*, opVFMADDPD*, opVFMADDPS*, opVFMADDSD*, opVFMADDSS*, opVFMADDSUB132PD*, opVFMADDSUB132PS*, opVFMADDSUB213PD*, opVFMADDSUB213PS*, opVFMADDSUB231PD*, opVFMADDSUB231PS*, opVFMADDSUBPD*, opVFMADDSUBPS*, opVFMSUB132PD*, opVFMSUB132PS*, opVFMSUB132SD*, opVFMSUB132SS*, opVFMSUB213PD*, opVFMSUB213PS*, opVFMSUB213SD*, opVFMSUB213SS*, opVFMSUB231PD*, opVFMSUB231PS*, opVFMSUB231SD*, opVFMSUB231SS*, opVFMSUBADD132PD*, opVFMSUBADD132PS*, opVFMSUBADD213PD*, opVFMSUBADD213PS*, opVFMSUBADD231PD*, opVFMSUBADD231PS*, opVFMSUBADDPD*, opVFMSUBADDPS*, opVFMSUBPD*, opVFMSUBPS*, opVFMSUBSD*, opVFMSUBSS*, opVFNMADD132PD*, opVFNMADD132PS*, opVFNMADD132SD*, opVFNMADD132SS*, opVFNMADD213PD*, opVFNMADD213PS*, opVFNMADD213SD*, opVFNMADD213SS*, opVFNMADD231PD*, opVFNMADD231PS*, opVFNMADD231SD*, opVFNMADD231SS*, opVFNMADDPD*, opVFNMADDPS*, opVFNMADDSD*, opVFNMADDSS*, opVFNMSUB132PD*, opVFNMSUB132PS*, opVFNMSUB132SD*, opVFNMSUB132SS*, opVFNMSUB213PD*, opVFNMSUB213PS*, opVFNMSUB213SD*, opVFNMSUB213SS*, opVFNMSUB231PD*, opVFNMSUB231PS*, opVFNMSUB231SD*, opVFNMSUB231SS*, opVFNMSUBPD*, opVFNMSUBPS*, opVFNMSUBSD*, opVFNMSUBSS*, opVFRCZPD*, opVFRCZPS*, opVFRCZSD*, opVFRCZSS*, opVGATHERDPD*, opVGATHERDPS*, opVGATHERQPD*, opVGATHERQPS*, opVHADDPD*, opVHADDPS*, opVHSUBPD*, opVHSUBPS*, opVINSERTF128*, opVINSERTI128*, opVINSERTPS*, opVLDDQU*, opVLDMXCSR*, opVMASKMOVDQU*, opVMASKMOVPD*, opVMASKMOVPS*, opVMAXPD*, opVMAXPS*, opVMAXSD*, opVMAXSS*, opVMINPD*, opVMINPS*, opVMINSD*, opVMINSS*, opVMOVAPD*, opVMOVAPS*, opVMOVD*, opVMOVDDUP*, opVMOVDQA*, opVMOVDQU*, opVMOVHLPS*, opVMOVHPD*, opVMOVHPS*, opVMOVLHPS*, opVMOVLPD*, opVMOVLPS*, opVPMOVMSKB*, opVMOVMSKPD*, opVMOVMSKPS*, opVMOVNTDQ*, opVMOVNTDQA*, opVMOVNTPD*, opVMOVNTPS*, opVMOVQ*, opVMOVSD*, opVMOVSHDUP*, opVMOVSLDUP*, opVMOVSS*, opVMOVUPD*, opVMOVUPS*, opVMPSADBW*, opVMULPD*, opVMULPS*, opVMULSD*, opVMULSS*, opVORPD*, opVORPS*, opVPABSB*, opVPABSD*, opVPABSW*, opVPACKSSDW*, opVPACKSSWB*, opVPACKUSDW*, opVPACKUSWB*, opVPADDB*, opVPADDD*, opVPADDQ*, opVPADDSB*, opVPADDSW*, opVPADDUSB*, opVPADDUSW*, opVPADDW*, opVPALIGNR*, opVPAND*, opVPANDN*, opVPAVGB*, opVPAVGW*, opVPBLENDD*, opVPBLENDVB*, opVPBLENDW*, opVPBROADCASTB*, opVPBROADCASTD*, opVPBROADCASTQ*, opVPBROADCASTW*, opVPCLMULQDQ*, opVPCMOV*, opVPCMPEQB*, opVPCMPEQD*, opVPCMPEQQ*, opVPCMPEQW*, opVPCMPESTRI*, opVPCMPESTRM*, opVPCMPGTB*, opVPCMPGTD*, opVPCMPGTQ*, opVPCMPGTW*, opVPCMPISTRI*, opVPCMPISTRM*, opVPCOMB*, opVPCOMD*, opVPCOMQ*, opVPCOMUB*, opVPCOMUD*, opVPCOMUQ*, opVPCOMUW*, opVPCOMW*, opVPERM2F128*, opVPERM2I128*, opVPERMD*, opVPERMIL2PD*, opVPERMIL2PS*, opVPERMILPD*, opVPERMILPS*, opVPERMPD*, opVPERMPS*, opVPERMQ*, opVPEXTRB*, opVPEXTRD*, opVPEXTRQ*, opVPEXTRW*, opVPGATHERDD*, opVPGATHERDQ*, opVPGATHERQD*, opVPGATHERQQ*, opVPHADDBD*, opVPHADDBQ*, opVPHADDBW*, opVPHADDD*, opVPHADDDQ*, opVPHADDSW*, opVPHADDUBD*, opVPHADDUBQ*, opVPHADDUBW*, opVPHADDUDQ*, opVPHADDUWD*, opVPHADDUWQ*, opVPHADDW*, opVPHADDWD*, opVPHADDWQ*, opVPHMINPOSUW*, opVPHSUBBW*, opVPHSUBD*, opVPHSUBDQ*, opVPHSUBSW*, opVPHSUBW*, opVPHSUBWD*, opVPINSRB*, opVPINSRD*, opVPINSRQ*, opVPINSRW*, opVPMACSDD*, opVPMACSDQH*, opVPMACSDQL*, opVPMACSSDD*, opVPMACSSDQH*, opVPMACSSDQL*, opVPMACSSWD*, opVPMACSSWW*, opVPMACSWD*, opVPMACSWW*, opVPMADCSSWD*, opVPMADDUBSW*, opVPMADDWD*, opVPMASKMOVD*, opVPMASKMOVQ*, opVPMAXSB*, opVPMAXSD*, opVPMAXSW*, opVPMAXUB*, opVPMAXUD*, opVPMAXUW*, opVPMINSB*, opVPMINSD*, opVPMINSW*, opVPMINUB*, opVPMINUD*, opVPMINUW*, opVPMOVSXBD*, opVPMOVSXBQ*, opVPMOVSXBW*, opVPMOVSXDQ*, opVPMOVSXWD*, opVPMOVSXWQ*, opVPMOVZXBD*, opVPMOVZXBQ*, opVPMOVZXBW*, opVPMOVZXDQ*, opVPMOVZXWD*, opVPMOVZXWQ*, opVPMULDQ*, opVPMULHRSW*, opVPMULHUW*, opVPMULHW*, opVPMULLD*, opVPMULLW*, opVPMULUDQ*, opVPOR*, opVPPERM*, opVPROTB*, opVPROTD*, opVPROTQ*, opVPROTW*, opVPSADBW*, opVPSHAB*, opVPSHAD*, opVPSHAQ*, opVPSHAW*, opVPSHLB*, opVPSHLD*, opVPSHLQ*, opVPSHLW*, opVPSHUFB*, opVPSHUFD*, opVPSHUFHW*, opVPSHUFLW*, opVPSIGNB*, opVPSIGND*, opVPSIGNW*, opVPSLLD*, opVPSLLDQ*, opVPSLLQ*, opVPSLLVD*, opVPSLLVQ*, opVPSLLW*, opVPSRAD*, opVPSRAVD*, opVPSRAW*, opVPSRLD*, opVPSRLDQ*, opVPSRLQ*, opVPSRLVD*, opVPSRLVQ*, opVPSRLW*, opVPSUBB*, opVPSUBD*, opVPSUBQ*, opVPSUBSB*, opVPSUBSW*, opVPSUBUSB*, opVPSUBUSW*, opVPSUBW*, opVPTEST*, opVPUNPCKHBW*, opVPUNPCKHDQ*, opVPUNPCKHQDQ*, opVPUNPCKHWD*, opVPUNPCKLBW*, opVPUNPCKLDQ*, opVPUNPCKLQDQ*, opVPUNPCKLWD*, opVPXOR*, opVRCPPS*, opVRCPSS*, opVROUNDPD*, opVROUNDPS*, opVROUNDSD*, opVROUNDSS*, opVRSQRTPS*, opVRSQRTSS*, opVSHUFPD*, opVSHUFPS*, opVSQRTPD*, opVSQRTPS*, opVSQRTSD*, opVSQRTSS*, opVSTMXCSR*, opVSUBPD*, opVSUBPS*, opVSUBSD*, opVSUBSS*, opVTESTPD*, opVTESTPS*, opVUCOMISD*, opVUCOMISS*, opVUNPCKHPD*, opVUNPCKHPS*, opVUNPCKLPD*, opVUNPCKLPS*, opVXORPD*, opVXORPS*, opVZEROALL*, opVZEROUPPER* : LONGINT (* FoxProgTools.Enum -l=8 -e opCode modRMExtension modRMBoth cb cw cd cp ib iw id iq rb rw rd rq mem64Operand mem128Operand fpStackOperand directMemoryOffset ~ *) CONST (* opcode flags, cf [AMD:3], pp. 39-40 *) opCode*= 0; modRMExtension*= 1; modRMBoth*= 2; cb*= 3; cw*= 4; cd*= 5; cp*= 6; ib*= 7; iw*= 8; id*= 9; iq*= 10; rb*= 11; rw*= 12; rd*= 13; rq*= 14; mem64Operand*= 15; mem128Operand*= 16; fpStackOperand*= 17; directMemoryOffset*= 18; Src1Prefix* = 19; Src2Prefix* = 20; CountPrefix*= 21; DestPrefix*=22; RXB*=23; TYPE Name = ARRAY 20 OF CHAR; OperandType* = SHORTINT; CPUOptions*= SET; Code*=CHAR; (* should be unsigned -- for emitter *) Instruction* = RECORD code-: ARRAY maxCodeLength OF Code; (* for the encoding cd. InitInstructions.Encode *) operands-: ARRAY maxNumberOperands OF OperandType; bitwidthOptions-: SET; cpuOptions-: SET; END; Mnemonic* = RECORD name-: ARRAY maxMnemonicNameLength OF CHAR; firstInstruction-, lastInstruction-: LONGINT; END; CPUType* = RECORD name-: Name; cpuOptions-: SET; END; Register* = RECORD name-: Name; (* name for debug output and for an assembler *) type-: OperandType; (* can be one of reg8, reg16, reg32, reg64, CRn, DRn, segReg, mmx, xmm, sti the particular value of reg8 ... sti does not have a meaning *) index-: SHORTINT; (* this index has a meaning for instruction encoding, it is the register index used in the instruction *) sizeInBytes-: SHORTINT; (* size in bytes *) END; VAR (* repository *) mnemonics-: ARRAY maxNumberMnemonics OF Mnemonic; numberMnemonics: LONGINT; instructions-: ARRAY maxNumberInstructions OF Instruction; numberInstructions: LONGINT; registers-: ARRAY numberRegisters OF Register; registersByClass-: ARRAY sti+1 OF ARRAY 17 OF LONGINT; cpus-: ARRAY maxCPUs OF CPUType; cpuCount: LONGINT; (* perform a binary search for the index of the specified mnemonic *) PROCEDURE FindMnemonic* (CONST mnem: ARRAY OF CHAR): LONGINT; VAR l, r, m: LONGINT; BEGIN l := 0; r := numberMnemonics; WHILE l # r DO m := (l + r) DIV 2; IF mnem < mnemonics[m].name THEN r := m; ELSIF mnem > mnemonics[m].name THEN l := m + 1; ELSE RETURN m; END END; RETURN none; END FindMnemonic; (* search for the register name and return it's index *) PROCEDURE FindRegister* (CONST reg: ARRAY OF CHAR): LONGINT; VAR i: LONGINT; BEGIN FOR i := 0 TO numberRegisters - 1 DO IF registers[i].name = reg THEN RETURN i END; END; RETURN none; END FindRegister; PROCEDURE RegisterType*(regNumber: LONGINT): OperandType; BEGIN IF regNumber = none THEN RETURN none ELSE RETURN registers[regNumber].type END END RegisterType; PROCEDURE RegisterIndex*(regNumber: LONGINT): SHORTINT; BEGIN IF regNumber = none THEN RETURN none ELSE RETURN registers[regNumber].index END END RegisterIndex; (* search for the CPU name and return it's index *) PROCEDURE FindCPU* (CONST cpu: ARRAY OF CHAR): LONGINT; VAR i: LONGINT; BEGIN FOR i := 0 TO cpuCount - 1 DO IF cpus[i].name = cpu THEN RETURN i END; END; RETURN none; END FindCPU; PROCEDURE StringToOperand(CONST name: ARRAY OF CHAR): SHORTINT; BEGIN IF name = "" THEN RETURN none ELSIF name = "1" THEN RETURN one; ELSIF name = "3" THEN RETURN three; ELSIF name = "reg8" THEN RETURN reg8; ELSIF name = "reg16" THEN RETURN reg16; ELSIF name = "reg32" THEN RETURN reg32; ELSIF name = "reg64" THEN RETURN reg64; ELSIF name = "reg" THEN RETURN reg3264; ELSIF name = "CRn" THEN RETURN CRn ELSIF name = "DRn" THEN RETURN DRn ELSIF name = "segReg" THEN RETURN segReg ELSIF name = "mmx" THEN RETURN mmx ELSIF name = "xmm" THEN RETURN xmm ELSIF name = "mem" THEN RETURN mem ELSIF name = "imm" THEN RETURN imm ELSIF name = "ioffset" THEN RETURN ioffset ELSIF name = "pntr1616" THEN RETURN pntr1616 ELSIF name = "pntr1632" THEN RETURN pntr1632 ELSIF name = "AL" THEN RETURN AL; ELSIF name = "AX" THEN RETURN AX; ELSIF name = "CL" THEN RETURN CL; ELSIF name = "CR8" THEN RETURN CR8; ELSIF name = "CS" THEN RETURN CS; ELSIF name = "DS" THEN RETURN DS; ELSIF name = "DX" THEN RETURN DX; ELSIF name = "EAX" THEN RETURN EAX; ELSIF name = "ECX" THEN RETURN ECX; ELSIF name = "ES" THEN RETURN ES; ELSIF name = "FS" THEN RETURN FS; ELSIF name = "GS" THEN RETURN GS; ELSIF name = "RAX" THEN RETURN RAX; ELSIF name = "SS" THEN RETURN SS; ELSIF name = "rAX" THEN RETURN rAX; ELSIF name = "ST(0)" THEN RETURN st0; ELSIF name = "ST(i)" THEN RETURN sti; ELSIF name = "imm16" THEN RETURN imm16 ELSIF name = "imm32" THEN RETURN imm32; ELSIF name = "imm64" THEN RETURN imm64 ELSIF name = "imm8" THEN RETURN imm8 ELSIF name = "uimm16" THEN RETURN uimm16 ELSIF name = "uimm32" THEN RETURN uimm32 ELSIF name = "uimm8" THEN RETURN uimm8 ELSIF name = "simm16" THEN RETURN simm16 ELSIF name = "simm32" THEN RETURN simm32 ELSIF name = "simm8" THEN RETURN simm8 ELSIF name = "mem256" THEN RETURN mem256 ELSIF name = "mem128" THEN RETURN mem128 ELSIF name = "mem16" THEN RETURN mem16 ELSIF name = "mem32" THEN RETURN mem32 ELSIF name = "mem64" THEN RETURN mem64 ELSIF name = "mem8" THEN RETURN mem8 ELSIF name = "moffset16" THEN RETURN moffset16 ELSIF name = "moffset32" THEN RETURN moffset32 ELSIF name = "moffset64" THEN RETURN moffset64 ELSIF name = "moffset8" THEN RETURN moffset8 ELSIF name = "rel16off" THEN RETURN rel16off ELSIF name = "rel32off" THEN RETURN rel32off ELSIF name = "rel8off" THEN RETURN rel8off ELSIF name = "reg/mem8" THEN RETURN regmem8; ELSIF name = "reg/mem16" THEN RETURN regmem16; ELSIF name = "reg/mem32" THEN RETURN regmem32; ELSIF name = "reg32/mem32" THEN RETURN regmem32; ELSIF name = "reg32/mem16" THEN RETURN reg32mem16; ELSIF name = "reg/mem64" THEN RETURN regmem64; ELSIF name = "reg64/mem64" THEN RETURN regmem64; ELSIF name = "mem14/28env" THEN RETURN mem; ELSIF name = "mem16&mem16" THEN RETURN mem; ELSIF name = "mem32&mem32" THEN RETURN mem; ELSIF name = "mem16:16" THEN RETURN mem; ELSIF name = "mem16:32" THEN RETURN mem; ELSIF name = "mem16:64" THEN RETURN mem; ELSIF name = "mem512env" THEN RETURN mem; ELSIF name = "mem80dec" THEN RETURN mem; ELSIF name = "mem80real" THEN RETURN mem; ELSIF name = "mem94/108env" THEN RETURN mem; ELSIF name = "mem2env" THEN RETURN mem16; ELSIF name = "xmm0" THEN RETURN xmm; ELSIF name = "xmm1" THEN RETURN xmm; ELSIF name = "xmm2" THEN RETURN xmm; ELSIF name = "xmm3" THEN RETURN xmm; ELSIF name = "xmm4" THEN RETURN xmm; ELSIF name = "xmm/mem32" THEN RETURN xmmmem32; ELSIF name = "xmm/mem64" THEN RETURN xmmmem64; ELSIF name = "xmm/mem128" THEN RETURN xmmmem128; ELSIF name = "xmm1/mem32" THEN RETURN xmmmem32; ELSIF name = "xmm1/mem64" THEN RETURN xmmmem64; ELSIF name = "xmm1/mem128" THEN RETURN xmmmem128; ELSIF name = "xmm2/mem8" THEN RETURN xmmmem8; ELSIF name = "xmm2/mem16" THEN RETURN xmmmem16; ELSIF name = "xmm2/mem32" THEN RETURN xmmmem32; ELSIF name = "xmm2/mem64" THEN RETURN xmmmem64; ELSIF name = "xmm2/mem128" THEN RETURN xmmmem128; ELSIF name = "xmm2/mem256" THEN RETURN xmmmem256; ELSIF name = "xmm2/m64" THEN RETURN xmmmem64; ELSIF name = "xmm2/m128" THEN RETURN xmmmem128; ELSIF name = "xmm3/mem32" THEN RETURN xmmmem32; ELSIF name = "xmm3/mem64" THEN RETURN xmmmem64; ELSIF name = "xmm3/mem128" THEN RETURN xmmmem128; ELSIF name = "xmm4/mem32" THEN RETURN xmmmem32; ELSIF name = "xmm4/mem64" THEN RETURN xmmmem64; ELSIF name = "xmm4/mem128" THEN RETURN xmmmem128; ELSIF name = "mmx/mem64" THEN RETURN mmxmem64; ELSIF name = "mmx1" THEN RETURN mmx; ELSIF name = "mmx2" THEN RETURN mmx; ELSIF name = "mmx1/mem64" THEN RETURN mmxmem64; ELSIF name = "mmx2/mem32" THEN RETURN mmxmem32; ELSIF name = "mmx2/mem64" THEN RETURN mmxmem64; ELSIF name = "pntr16:16" THEN RETURN pntr1616; ELSIF name = "pntr16:32" THEN RETURN pntr1632; ELSIF name = "mem16int" THEN RETURN mem16; ELSIF name = "mem32int" THEN RETURN mem32; ELSIF name = "mem32real" THEN RETURN mem32; ELSIF name = "mem64int" THEN RETURN mem64; ELSIF name = "mem64real" THEN RETURN mem64; ELSIF name = "ymm" THEN RETURN ymm; ELSIF name = "ymm0" THEN RETURN ymm; ELSIF name = "ymm1" THEN RETURN ymm; ELSIF name = "ymm2" THEN RETURN ymm; ELSIF name = "ymm3" THEN RETURN ymm; ELSIF name = "ymm4" THEN RETURN ymm; ELSIF name = "ymm1/mem256" THEN RETURN ymmmem256; ELSIF name = "ymm1/m256" THEN RETURN ymmmem256; ELSIF name = "ymm2/mem256" THEN RETURN ymmmem256; ELSIF name = "ymm2/m256" THEN RETURN ymmmem256; ELSIF name = "ymm3/mem256" THEN RETURN ymmmem256; ELSIF name = "ymm1/mem128" THEN RETURN ymmmem128; ELSIF name = "ymm1/m128" THEN RETURN ymmmem128; ELSIF name = "ymm2/mem128" THEN RETURN ymmmem128; ELSIF name = "ymm2/m128" THEN RETURN ymmmem128; ELSIF name = "ymm3/mem128" THEN RETURN ymmmem128; ELSIF name = "ymm4/mem256" THEN RETURN ymmmem256; ELSIF name = "vm32x" THEN RETURN vm32x ELSIF name = "vm32y" THEN RETURN vm32y ELSIF name = "vm64x" THEN RETURN vm64x ELSIF name = "vm64y" THEN RETURN vm64y ELSIF name = "m2z" THEN RETURN m2z ELSE HALT(200) END; END StringToOperand; PROCEDURE ParseOperand(CONST op: ARRAY OF CHAR; VAR at: LONGINT): SHORTINT; VAR name: ARRAY 32 OF CHAR; i: LONGINT; BEGIN i := 0; WHILE(op[at] # 0X) & (op[at] # ",") DO name[i] := op[at]; INC(i); INC(at); END; name[i] := 0X; IF op[at] = "," THEN INC(at) END; RETURN StringToOperand(name); END ParseOperand; (** setup instruction and mnemonic tables **) PROCEDURE InitInstructions; VAR PROCEDURE AddMnemonic(VAR op: LONGINT; CONST name: ARRAY OF CHAR); BEGIN op := numberMnemonics; COPY (name, mnemonics[op].name); mnemonics[op].firstInstruction := -1; INC(numberMnemonics); END AddMnemonic; PROCEDURE HexOrd (ch: CHAR): INTEGER; BEGIN IF ("0" <= ch) & (ch <= "9") THEN RETURN ORD (ch) - ORD ("0") ELSIF ("A" <= ch) & (ch <= "F") THEN RETURN ORD (CAP (ch)) - ORD ("A") + 10 ELSE HALT(100); END END HexOrd; PROCEDURE Encode(CONST charcode: ARRAY OF CHAR; VAR code: ARRAY OF Code); (* simple encoding: code = { opCode number |modRMBoth |modRMExtension number |cb|cw|cd|cp |ib|iw|id|iq |m6|m1 |+i|+o |rb|rw|rd|rq } none { none } all symbols 8 bit wide, numbers also 8 bits wide *) VAR i,k,length: SHORTINT; ch1,ch2: CHAR; BEGIN i := 0; k := 0; WHILE(charcode[2*i] # 0X) DO ch1 := charcode[2*i]; ch2 := charcode[2*i+1]; CASE ch1 OF '0'..'9','A'..'F': CASE ch2 OF '0'..'9','A'..'F': code[k] := CHR(opCode);INC(k); code[k] := CHR(HexOrd(ch1)*10H+HexOrd(ch2)); INC(k); ELSE HALT(100) END; |'/': CASE ch2 OF 'r': code[k] := CHR(modRMBoth); INC(k); |'0'..'7': code[k] := CHR(modRMExtension); INC(k); code[k] := CHR(HexOrd(ch2)); INC(k); ELSE HALT(100) END; |'c': CASE ch2 OF 'b': code[k] := CHR(cb); INC(k); |'w': code[k] := CHR(cw); INC(k); |'d': code[k] := CHR(cd); INC(k); |'p': code[k] := CHR(cp); INC(k); ELSE HALT(100) END; |'i': CASE ch2 OF 'b': code[k] := CHR(ib); INC(k); |'w': code[k] := CHR(iw); INC(k); |'d': code[k] := CHR(id); INC(k); |'q': code[k] := CHR(iq); INC(k); ELSE HALT(100) END; |'m': CASE ch2 OF '6': code[k] := CHR(mem64Operand); INC(k); |'1': code[k] := CHR(mem128Operand); INC(k); ELSE HALT(100) END; |'+': CASE ch2 OF 'i': code[k] := CHR(fpStackOperand); INC(k); |'o': code[k] := CHR(directMemoryOffset); INC(k); ELSE HALT(100) END; |'r': CASE ch2 OF 'b': code[k] := CHR(rb); INC(k); |'w': code[k] := CHR(rw); INC(k); |'d': code[k] := CHR(rd); INC(k); |'q': code[k] := CHR(rq); INC(k); ELSE HALT(100) END; ELSE HALT(100) END; INC(i); END; length := k; WHILE(k < LEN(code)) DO code[k] := CHR(none); INC(k); END; END Encode; PROCEDURE EncodeV(CONST charcode: ARRAY OF CHAR; VAR code: ARRAY OF Code); (* simple encoding: code = { opCode number |modRMBoth |modRMExtension number |cb|cw|cd|cp |ib|iw|id|iq |m6|m1 |+i|+o |rb|rw|rd|rq } none { none } all symbols 8 bit wide, numbers also 8 bits wide *) PROCEDURE GetCode(CONST charcode: ARRAY OF CHAR; VAR at: LONGINT; VAR cd: ARRAY OF CHAR): BOOLEAN; VAR i: LONGINT; BEGIN WHILE(charcode[at] = " ") DO INC(at) END; IF charcode[at] = 0X THEN RETURN FALSE END; i := 0; WHILE (charcode[at] # " ") & (charcode[at] # 0X) DO cd[i] := charcode[at]; INC(i); INC(at); END; cd[i] := 0X; RETURN TRUE; END GetCode; VAR i,k,length: SHORTINT; ch1,ch2: CHAR; cdc: ARRAY 32 OF CHAR; at,mul,val: LONGINT; BEGIN i := 0; k := 0; at := 0; WHILE(GetCode(charcode,at,cdc)) DO ch1 := cdc[0]; ch2 := cdc[1]; IF (ch2 = ".") & ((ch1="0") OR (ch1="1") OR (ch1="X")) THEN mul := 80H; val := 0; i := 0; code[k] := CHR(opCode); WHILE (cdc[i] # 0X) DO IF (cdc[i] ="0") OR (cdc[i]="X") THEN mul := mul DIV 2; ELSIF cdc[i] = "1" THEN INC(val, mul); mul := mul DIV 2; ELSIF cdc[i] = "." (* next *) THEN ELSIF cdc[i] = "c" THEN INC(i); ASSERT(cdc[i] ="o"); INC(i); ASSERT(cdc[i] ="u"); INC(i); ASSERT(cdc[i] ="n"); INC(i); ASSERT(cdc[i] ="t"); code[k] := CHR(CountPrefix); mul := mul DIV 10H; ELSIF cdc[i] = "d" THEN INC(i); ASSERT(cdc[i] ="e"); INC(i); ASSERT(cdc[i] ="s"); INC(i); ASSERT(cdc[i] ="t"); code[k] := CHR(DestPrefix); mul := mul DIV 10H; ELSIF cdc[i] = "s" THEN INC(i); ASSERT(cdc[i] ="r"); INC(i); ASSERT(cdc[i] ="c"); code[k] := CHR(Src1Prefix); ASSERT(mul = 64); IF (cdc[i+1] = "1") THEN INC(i); ELSIF (cdc[i+1] = "2") THEN code[k] := CHR(Src2Prefix); INC(i); END; mul := mul DIV 10H; ELSE HALT(100); END; INC(i); END; INC(k); code[k] := CHR(val); INC(k); ELSIF (ch1="R") THEN code[k] := CHR(RXB); INC(k); IF (cdc = "RXB.00001") OR (cdc ="RXB.01") THEN code[k] := CHR(1); ELSIF (cdc ="RXB.00011") OR (cdc = "RXB.03") THEN code[k] := CHR(3); ELSIF (cdc ="RXB.00010") OR (cdc = "RXB.2") OR (cdc = "RXB.02") THEN code[k] := CHR(2); ELSIF (cdc ="RXB.01000") OR (cdc ="RXB.08") THEN code[k] := CHR(8); ELSIF cdc ="RXB.09" THEN code[k] := CHR(9); ELSE HALT(100) END; INC(k); ELSE CASE ch1 OF '0'..'9','A'..'F': CASE ch2 OF '0'..'9','A'..'F': code[k] := CHR(opCode);INC(k); code[k] := CHR(HexOrd(ch1)*10H+HexOrd(ch2)); INC(k); ELSE HALT(100) END; |'/': CASE ch2 OF 'r': code[k] := CHR(modRMBoth); INC(k); |'0'..'7': code[k] := CHR(modRMExtension); INC(k); code[k] := CHR(HexOrd(ch2)); INC(k); ELSE IF cdc = "/imm8" THEN (*todo*) ELSIF cdc = "/is4" THEN (*todo*) ELSIF cdc = "/ib" THEN code[k] := CHR(ib); INC(k); ELSE HALT(100) END; END; |'c': CASE ch2 OF 'b': code[k] := CHR(cb); INC(k); |'w': code[k] := CHR(cw); INC(k); |'d': code[k] := CHR(cd); INC(k); |'p': code[k] := CHR(cp); INC(k); ELSE HALT(100) END; |'i': CASE ch2 OF 'b': code[k] := CHR(ib); INC(k); |'w': code[k] := CHR(iw); INC(k); |'d': code[k] := CHR(id); INC(k); |'q': code[k] := CHR(iq); INC(k); ELSE IF cdc = "is4" THEN (*todo*) ELSIF cdc = "is5" THEN (*todo*) ELSE HALT(100) END; END; |'m': CASE ch2 OF '6': code[k] := CHR(mem64Operand); INC(k); |'1': code[k] := CHR(mem128Operand); INC(k); ELSE HALT(100) END; |'+': CASE ch2 OF 'i': code[k] := CHR(fpStackOperand); INC(k); |'o': code[k] := CHR(directMemoryOffset); INC(k); ELSE HALT(100) END; |'r': CASE ch2 OF 'b': code[k] := CHR(rb); INC(k); |'w': code[k] := CHR(rw); INC(k); |'d': code[k] := CHR(rd); INC(k); |'q': code[k] := CHR(rq); INC(k); ELSE HALT(100) END; ELSE HALT(100) END; INC(i); END; END; length := k; WHILE(k < LEN(code)) DO code[k] := CHR(none); INC(k); END; END EncodeV; PROCEDURE AddInstructionV(mnemonic: LONGINT; CONST operands, code: ARRAY OF CHAR); VAR i, at: LONGINT; name: ARRAY 32 OF CHAR; BEGIN i := 0; at := 0; WHILE (i