Added placeholders for IBTS and XBTS (80386 opcodes on A0-B0 steppings only)
This commit is contained in:
parent
6dcb644a05
commit
8bd1794928
7 changed files with 139 additions and 75 deletions
|
|
@ -6,8 +6,7 @@ problems were fixed by a later stepping, seems virtually impossible at this late
|
|||
|
||||
I won't make the attempt here, either. Using information from various sources, I'll start with an overview
|
||||
of the steppings, including how each stepping was externally marked and internally identified, along with lists
|
||||
of associated errata, then move on to more detailed errata information (from Intel's own documents), and end
|
||||
with a summary of undocumented 80386 instructions.
|
||||
of associated errata, then move on to more detailed errata information, based on Intel's own documents.
|
||||
|
||||
### Steppings
|
||||
|
||||
|
|
@ -866,23 +865,15 @@ Here's more information on the opcodes (IBTS and XBTS) that were removed from th
|
|||
CPU: 80386 step A0-B0 only
|
||||
Type of Instruction: User
|
||||
|
||||
Instruction: IBTS base,bitoffset,len,sorc
|
||||
|
||||
Description:
|
||||
Write bit string length <len> bits from
|
||||
<sorc> [bits <len> .. 0 ] (lowest bits) to bitfield,
|
||||
defined by <base> and bitsoffset <bitoffset> from this base
|
||||
to start of the field to write. String write from this start
|
||||
field bit to higher memory addresses or register bits.
|
||||
Instruction: IBTS base,bitoffset,len,src
|
||||
|
||||
Flags Affected: None
|
||||
|
||||
CPU mode: RM,PM,VM
|
||||
|
||||
+++++++++++++++++++++++
|
||||
Physical Form: IBTS r/m16,AX,CL,r16
|
||||
IBTS r/m32,EAX,CL,r32
|
||||
COP (Code of Operation) : 0FH A7H
|
||||
IBTS r/m16,AX,CL,r16
|
||||
IBTS r/m32,EAX,CL,r32
|
||||
COP (Code of Operation): 0FH A7H
|
||||
|
||||
Clocks: IBTS
|
||||
80386: 12/19
|
||||
|
|
@ -894,29 +885,15 @@ Here's more information on the opcodes (IBTS and XBTS) that were removed from th
|
|||
CPU: 80386 step A0-B0 only
|
||||
Type of Instruction: User
|
||||
|
||||
Instruction: XBTS dest,base,bitoffset,len
|
||||
|
||||
Description:
|
||||
Write bit string length <len> bits from bitfield, defined by
|
||||
<base> and bitsoffset <bitoffset> from this base to start of
|
||||
the field to read. String read from this start field bit to
|
||||
higher memory addresses or register bits.
|
||||
And after it string placed to <dest> operand, lowest bit of
|
||||
register or memory to bit 0 of <dest>.
|
||||
|
||||
Note: Use SHLD/SHRD instructions for extract bits strings.
|
||||
On 80386 steps B1+ this opcode generation INT 6,
|
||||
and on some of 486 other instruction replace this
|
||||
instruction opcode.
|
||||
Instruction: XBTS dst,base,bitoffset,len
|
||||
|
||||
Flags Affected: None
|
||||
|
||||
CPU mode: RM,PM,VM
|
||||
|
||||
+++++++++++++++++++++++
|
||||
Physical Form: XBTS r16,r/m16,AX,CL
|
||||
XBTS r16,r/m16,AX,CL
|
||||
XBTS r32,r/m32,EAX,CL
|
||||
COP (Code of Operation) : 0FH A6H
|
||||
COP (Code of Operation): 0FH A6H
|
||||
|
||||
Clocks: XBTS
|
||||
80386: 6/13
|
||||
|
|
|
|||
|
|
@ -327,25 +327,25 @@ if (DEBUGGER) {
|
|||
FCOM: 40, FCOMP: 41, FDIV: 42, FDIVR: 43, FIADD: 44, FICOM: 45, FICOMP: 46, FIDIV: 47,
|
||||
FIDIVR: 48, FILD: 49, FIMUL: 50, FIST: 51, FISTP: 52, FISUB: 53, FISUBR: 54, FLD: 55,
|
||||
FLDCW: 56, FLDENV: 57, FMUL: 58, FNSAVE: 59, FNSTCW: 60, FNSTENV:61, FNSTSW: 62, FRSTOR: 63,
|
||||
FS: 64, FST: 65, FSTP: 66, FSUB: 67, FSUBR: 68, GS: 69, HLT: 70, IDIV: 71,
|
||||
IMUL: 72, IN: 73, INC: 74, INS: 75, INT: 76, INT3: 77, INTO: 78, IRET: 79,
|
||||
JBE: 80, JC: 81, JCXZ: 82, JG: 83, JGE: 84, JL: 85, JLE: 86, JMP: 87,
|
||||
JA: 88, JNC: 89, JNO: 90, JNP: 91, JNS: 92, JNZ: 93, JO: 94, JP: 95,
|
||||
JS: 96, JZ: 97, LAHF: 98, LAR: 99, LDS: 100, LEA: 101, LEAVE: 102, LES: 103,
|
||||
LFS: 104, LGDT: 105, LGS: 106, LIDT: 107, LLDT: 108, LMSW: 109, LOADALL:110, LOCK: 111,
|
||||
LODSB: 112, LODSW: 113, LOOP: 114, LOOPNZ: 115, LOOPZ: 116, LSL: 117, LSS: 118, LTR: 119,
|
||||
MOV: 120, MOVSB: 121, MOVSW: 122, MOVSX: 123, MOVZX: 124, MUL: 125, NEG: 126, NOP: 127,
|
||||
NOT: 128, OR: 129, OS: 130, OUT: 131, OUTS: 132, POP: 133, POPA: 134, POPF: 135,
|
||||
PUSHF: 136, PUSHA: 137, PUSH: 138, RCL: 139, RCR: 140, REPNZ: 141, REPZ: 142, RET: 143,
|
||||
RETF: 144, ROL: 145, ROR: 146, SAHF: 147, SALC: 148, SAR: 149, SBB: 150, SCASB: 151,
|
||||
SCASW: 152, SETBE: 153, SETC: 154, SETG: 155, SETGE: 156, SETL: 157, SETLE: 158, SETNBE: 159,
|
||||
SETNC: 160, SETNO: 161, SETNP: 162, SETNS: 163, SETNZ: 164, SETO: 165, SETP: 166, SETS: 167,
|
||||
SETZ: 168, SGDT: 169, SHL: 170, SHLD: 171, SHR: 172, SHRD: 173, SIDT: 174, SLDT: 175,
|
||||
SMSW: 176, SS: 177, STC: 178, STD: 179, STI: 180, STOSB: 181, STOSW: 182, STR: 183,
|
||||
SUB: 184, TEST: 185, VERR: 186, VERW: 187, WAIT: 188, XCHG: 189, XLAT: 190, XOR: 191,
|
||||
GRP1B: 192, GRP1W: 193, GRP1SW: 194, GRP2B: 195, GRP2W: 196, GRP2B1: 197, GRP2W1: 198, GRP2BC: 199,
|
||||
GRP2WC: 200, GRP3B: 201, GRP3W: 202, GRP4B: 203, GRP4W: 204, OP0F: 205, GRP6: 206, GRP7: 207,
|
||||
GRP8: 208
|
||||
FS: 64, FST: 65, FSTP: 66, FSUB: 67, FSUBR: 68, GS: 69, HLT: 70, IBTS: 71,
|
||||
IDIV: 72, IMUL: 73, IN: 74, INC: 75, INS: 76, INT: 77, INT3: 78, INTO: 79,
|
||||
IRET: 80, JBE: 81, JC: 82, JCXZ: 83, JG: 84, JGE: 85, JL: 86, JLE: 87,
|
||||
JMP: 88, JA: 89, JNC: 90, JNO: 91, JNP: 92, JNS: 93, JNZ: 94, JO: 95,
|
||||
JP: 96, JS: 97, JZ: 98, LAHF: 99, LAR: 100, LDS: 101, LEA: 102, LEAVE: 103,
|
||||
LES: 104, LFS: 105, LGDT: 106, LGS: 107, LIDT: 108, LLDT: 109, LMSW: 110, LOADALL:111,
|
||||
LOCK: 112, LODSB: 113, LODSW: 114, LOOP: 115, LOOPNZ: 116, LOOPZ: 117, LSL: 118, LSS: 119,
|
||||
LTR: 120, MOV: 121, MOVSB: 122, MOVSW: 123, MOVSX: 124, MOVZX: 125, MUL: 126, NEG: 127,
|
||||
NOP: 128, NOT: 129, OR: 130, OS: 131, OUT: 132, OUTS: 133, POP: 134, POPA: 135,
|
||||
POPF: 136, PUSHF: 137, PUSHA: 138, PUSH: 139, RCL: 140, RCR: 141, REPNZ: 142, REPZ: 143,
|
||||
RET: 144, RETF: 145, ROL: 146, ROR: 147, SAHF: 148, SALC: 149, SAR: 150, SBB: 151,
|
||||
SCASB: 152, SCASW: 153, SETBE: 154, SETC: 155, SETG: 156, SETGE: 157, SETL: 158, SETLE: 159,
|
||||
SETNBE: 160, SETNC: 161, SETNO: 162, SETNP: 163, SETNS: 164, SETNZ: 165, SETO: 166, SETP: 167,
|
||||
SETS: 168, SETZ: 169, SGDT: 170, SHL: 171, SHLD: 172, SHR: 173, SHRD: 174, SIDT: 175,
|
||||
SLDT: 176, SMSW: 177, SS: 178, STC: 179, STD: 180, STI: 181, STOSB: 182, STOSW: 183,
|
||||
STR: 184, SUB: 185, TEST: 186, VERR: 187, VERW: 188, WAIT: 189, XBTS: 190, XCHG: 191,
|
||||
XLAT: 192, XOR: 193, GRP1B: 194, GRP1W: 195, GRP1SW: 196, GRP2B: 197, GRP2W: 198, GRP2B1: 199,
|
||||
GRP2W1: 200, GRP2BC: 201, GRP2WC: 202, GRP3B: 203, GRP3W: 204, GRP4B: 205, GRP4W: 206, OP0F: 207,
|
||||
GRP6: 208, GRP7: 209, GRP8: 210
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -360,22 +360,23 @@ if (DEBUGGER) {
|
|||
"FCOM", "FCOMP", "FDIV", "FDIVR", "FIADD", "FICOM", "FICOMP", "FIDIV",
|
||||
"FIDIVR", "FILD", "FIMUL", "FIST", "FISTP", "FISUB", "FISUBR", "FLD",
|
||||
"FLDCW", "FLDENV", "FMUL", "FNSAVE", "FNSTCW", "FNSTENV","FNSTSW", "FRSTOR",
|
||||
"FS:", "FST", "FSTP", "FSUB", "FSUBR", "GS:", "HLT", "IDIV",
|
||||
"IMUL", "IN", "INC", "INS", "INT", "INT3", "INTO", "IRET",
|
||||
"JBE", "JC", "JCXZ", "JG", "JGE", "JL", "JLE", "JMP",
|
||||
"JA", "JNC", "JNO", "JNP", "JNS", "JNZ", "JO", "JP",
|
||||
"JS", "JZ", "LAHF", "LAR", "LDS", "LEA", "LEAVE", "LES",
|
||||
"LFS", "LGDT", "LGS", "LIDT", "LLDT", "LMSW", "LOADALL","LOCK",
|
||||
"LODSB", "LODSW", "LOOP", "LOOPNZ", "LOOPZ", "LSL", "LSS", "LTR",
|
||||
"MOV", "MOVSB", "MOVSW", "MOVSX", "MOVZX", "MUL", "NEG", "NOP",
|
||||
"NOT", "OR", "OS:", "OUT", "OUTS", "POP", "POPA", "POPF",
|
||||
"PUSHF", "PUSHA", "PUSH", "RCL", "RCR", "REPNZ", "REPZ", "RET",
|
||||
"RETF", "ROL", "ROR", "SAHF", "SALC", "SAR", "SBB", "SCASB",
|
||||
"SCASW", "SETBE", "SETC", "SETG", "SETGE", "SETL", "SETLE", "SETNBE",
|
||||
"SETNC", "SETNO", "SETNP", "SETNS", "SETNZ", "SETO", "SETP", "SETS",
|
||||
"SETZ", "SGDT", "SHL", "SHLD", "SHR", "SHRD", "SIDT", "SLDT",
|
||||
"SMSW", "SS:", "STC", "STD", "STI", "STOSB", "STOSW", "STR",
|
||||
"SUB", "TEST", "VERR", "VERW", "WAIT", "XCHG", "XLAT", "XOR"
|
||||
"FS:", "FST", "FSTP", "FSUB", "FSUBR", "GS:", "HLT", "IBTS",
|
||||
"IDIV", "IMUL", "IN", "INC", "INS", "INT", "INT3", "INTO",
|
||||
"IRET", "JBE", "JC", "JCXZ", "JG", "JGE", "JL", "JLE",
|
||||
"JMP", "JA", "JNC", "JNO", "JNP", "JNS", "JNZ", "JO",
|
||||
"JP", "JS", "JZ", "LAHF", "LAR", "LDS", "LEA", "LEAVE",
|
||||
"LES", "LFS", "LGDT", "LGS", "LIDT", "LLDT", "LMSW", "LOADALL",
|
||||
"LOCK", "LODSB", "LODSW", "LOOP", "LOOPNZ", "LOOPZ", "LSL", "LSS",
|
||||
"LTR", "MOV", "MOVSB", "MOVSW", "MOVSX", "MOVZX", "MUL", "NEG",
|
||||
"NOP", "NOT", "OR", "OS:", "OUT", "OUTS", "POP", "POPA",
|
||||
"POPF", "PUSHF", "PUSHA", "PUSH", "RCL", "RCR", "REPNZ", "REPZ",
|
||||
"RET", "RETF", "ROL", "ROR", "SAHF", "SALC", "SAR", "SBB",
|
||||
"SCASB", "SCASW", "SETBE", "SETC", "SETG", "SETGE", "SETL", "SETLE",
|
||||
"SETNBE", "SETNC", "SETNO", "SETNP", "SETNS", "SETNZ", "SETO", "SETP",
|
||||
"SETS", "SETZ", "SGDT", "SHL", "SHLD", "SHR", "SHRD", "SIDT",
|
||||
"SLDT", "SMSW", "SS:", "STC", "STD", "STI", "STOSB", "STOSW",
|
||||
"STR", "SUB", "TEST", "VERR", "VERW", "WAIT", "XBTS", "XCHG",
|
||||
"XLAT", "XOR"
|
||||
];
|
||||
|
||||
Debugger.CPU_8086 = 0;
|
||||
|
|
@ -981,6 +982,8 @@ if (DEBUGGER) {
|
|||
0xA3: [Debugger.INS.BT, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_IN | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
|
||||
0xA4: [Debugger.INS.SHLD, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
|
||||
0xA5: [Debugger.INS.SHLD, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN],
|
||||
0xA6: [Debugger.INS.XBTS, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_AX | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN],
|
||||
0xA7: [Debugger.INS.IBTS, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_IMPREG | Debugger.TYPE_AX | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
|
||||
0xA8: [Debugger.INS.PUSH, Debugger.TYPE_GS | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0xA9: [Debugger.INS.POP, Debugger.TYPE_GS | Debugger.TYPE_OUT | Debugger.TYPE_80386],
|
||||
0xAB: [Debugger.INS.BTS, Debugger.TYPE_MODRM | Debugger.TYPE_VWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_VWORD | Debugger.TYPE_IN],
|
||||
|
|
|
|||
|
|
@ -44,10 +44,12 @@ var X86 = {
|
|||
MODEL_80386: 80386,
|
||||
|
||||
/*
|
||||
* CPU stepping identifiers (supported)
|
||||
* 80386 CPU stepping identifiers (supported)
|
||||
*/
|
||||
STEPPING_B1: 0xB1, // our version of the B1 stepping also includes the infamous 32-bit multiplication bug
|
||||
STEPPING_B2: 0xB2, // this is an imaginary stepping that simply means "B1 without the 32-bit multiplication bug" (ie, a B1 with the "double sigma" stamp)
|
||||
STEPPING_80386_A0: (80386+0xA0),
|
||||
STEPPING_80386_B0: (80386+0xB0), // for now, the only B0 difference is support for XBTS
|
||||
STEPPING_80386_B1: (80386+0xB1), // our version of the B1 stepping also includes the infamous 32-bit multiplication bug
|
||||
STEPPING_80386_B2: (80386+0xB2), // this is an imaginary stepping that simply means "B1 without the 32-bit multiplication bug" (ie, a B1 with the "double sigma" stamp)
|
||||
|
||||
/*
|
||||
* This constant is used to mark points in the code where the physical address being returned
|
||||
|
|
|
|||
|
|
@ -110,8 +110,13 @@ function X86CPU(parmsCPU)
|
|||
{
|
||||
this.model = parmsCPU['model'] || X86.MODEL_8088;
|
||||
|
||||
/*
|
||||
* We take the 'stepping' value, convert it to a hex value, and then add that to the model to provide
|
||||
* a single value that's unique for any given CPU stepping. If no stepping is provided, then stepping
|
||||
* is equal to model.
|
||||
*/
|
||||
var stepping = parmsCPU['stepping'];
|
||||
this.stepping = (stepping? str.parseInt(stepping, 16) : 0);
|
||||
this.stepping = this.model + (stepping? str.parseInt(stepping, 16) : 0);
|
||||
|
||||
var nCyclesDefault = 0;
|
||||
switch(this.model) {
|
||||
|
|
@ -812,6 +817,10 @@ X86CPU.prototype.initProcessor = function()
|
|||
for (bOpcode in X86.aOps0F386) {
|
||||
this.aOps0F[+bOpcode] = X86.aOps0F386[bOpcode];
|
||||
}
|
||||
if (this.stepping >= X86.STEPPING_80386_A0 && this.stepping <= X86.STEPPING_80386_B0) {
|
||||
this.aOps0F[0xA6] = X86.opXBTS;
|
||||
this.aOps0F[0xA7] = X86.opIBTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -683,6 +683,28 @@ X86.fnDECw = function(dst, src)
|
|||
return w & this.maskData;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnIBTS(dst, src)
|
||||
*
|
||||
* As best I can determine, this function copies the specified bits from src (starting at bit 0 for CL
|
||||
* bits) to dst (starting at bit offset in AX). For register operands, that's simple enough.
|
||||
*
|
||||
* TODO: If dst refers to a memory location, then the bit index may refer to higher memory locations, just
|
||||
* like the BT/BTC/BTR/BTS instructions. For an instruction that no one was really able to use, except
|
||||
* as a CPU stepping discriminator, that doesn't seem worth the effort.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnIBTS = function(dst, src)
|
||||
{
|
||||
var shift = (this.regEAX & this.maskData);
|
||||
var mask = ((1 << (this.regECX & 0x1f)) - 1);
|
||||
return (dst & ~(mask << shift)) | ((src & mask) << shift);
|
||||
};
|
||||
|
||||
/**
|
||||
* fnSet64(lo, hi)
|
||||
*
|
||||
|
|
@ -2033,11 +2055,11 @@ X86.fnMULw = function(dst, src)
|
|||
this.regMDHi = (result >> 16) & 0xffff;
|
||||
} else {
|
||||
X86.fnMUL32.call(this, dst, this.regEAX);
|
||||
if (this.model == X86.MODEL_80386 && this.stepping == X86.STEPPING_B1) {
|
||||
if (this.stepping == X86.STEPPING_80386_B1) {
|
||||
if (this.regEAX == 0x0417A000 && dst == 0x00000081) {
|
||||
/*
|
||||
* In this case, the result should be 0x20FE7A000 (ie, regMDHi should be 0x2), and I'm not
|
||||
* sure what the typical failure would look like, so I'll just set regMDHi to 0.
|
||||
* Normally, the result should be 0x20FE7A000 (ie, regMDHi should be 0x2).
|
||||
* I'm not sure what a typical failure looked like, so I'll just set regMDHi to 0.
|
||||
*
|
||||
* If you want a B1 stepping without this 32-bit multiplication flaw, select the B2 stepping.
|
||||
*/
|
||||
|
|
@ -3538,6 +3560,30 @@ X86.fnVERW = function(dst, src)
|
|||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnXBTS(dst, src)
|
||||
*
|
||||
* As best I can determine, this function copies the specified bits from src (starting at the bit offset
|
||||
* in AX, for the bit length in CL) to dst (starting at bit 0). For register operands, that's simple enough.
|
||||
*
|
||||
* TODO: If src refers to a memory location, then the bit index may refer to higher memory locations, just
|
||||
* like the BT/BTC/BTR/BTS instructions. For an instruction that no one was really able to use, except
|
||||
* as a CPU stepping discriminator, that doesn't seem worth the effort.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnXBTS = function(dst, src)
|
||||
{
|
||||
/*
|
||||
* Shift src right by the bit offset in [E]AX, then apply a mask equal to the number of bits in CL,
|
||||
* then mask the resulting bit string with the current OPERAND size.
|
||||
*/
|
||||
return ((src >> (this.regEAX & this.maskData)) & ((1 << (this.regECX & 0x1f)) - 1)) & this.maskData;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnXCHGrb(dst, src)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1166,6 +1166,32 @@ X86.opSHLDcl = function SHLDcl()
|
|||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7);
|
||||
};
|
||||
|
||||
/**
|
||||
* opXBTS()
|
||||
*
|
||||
* op=0x0F,0xA6 (XBTS reg,mem/reg,[E]AX,CL)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
*/
|
||||
X86.opXBTS = function XBTS()
|
||||
{
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86.fnXBTS);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 6 : 13);
|
||||
};
|
||||
|
||||
/**
|
||||
* opIBTS()
|
||||
*
|
||||
* op=0x0F,0xA7 (IBTS mem/reg,[E]AX,CL,reg)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
*/
|
||||
X86.opIBTS = function IBTS()
|
||||
{
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86.fnIBTS);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 12 : 19);
|
||||
};
|
||||
|
||||
/**
|
||||
* opPUSHGS()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2952,9 +2952,10 @@ X86.opSTOSb = function STOSb()
|
|||
* only EDI in the case of STOS. The other instructions mentioned below monkey with different
|
||||
* registers, so read the errata carefully.
|
||||
*
|
||||
* TODO: Extend this errata to STOSW, as well as MOVSB, MOVSW, INSB, and INSW.
|
||||
* TODO: Extend this errata to STOSW, as well as MOVSB, MOVSW, INSB, and INSW. Also, scope out the
|
||||
* extent to which this errara also existed on earlier steppings.
|
||||
*/
|
||||
if (this.model == X86.MODEL_80386 && this.stepping == X86.STEPPING_B1) {
|
||||
if (this.stepping == X86.STEPPING_80386_B1) {
|
||||
if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE) != (this.getByte(this.regLIP) != X86.OPCODE.AS)) {
|
||||
maskAddr ^= (0xffff0000|0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue