Added placeholders for IBTS and XBTS (80386 opcodes on A0-B0 steppings only)

This commit is contained in:
Jeff Parsons 2015-10-29 22:44:33 -07:00
commit 8bd1794928
7 changed files with 139 additions and 75 deletions

View file

@ -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 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 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 of associated errata, then move on to more detailed errata information, based on Intel's own documents.
with a summary of undocumented 80386 instructions.
### Steppings ### 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 CPU: 80386 step A0-B0 only
Type of Instruction: User Type of Instruction: User
Instruction: IBTS base,bitoffset,len,sorc Instruction: IBTS base,bitoffset,len,src
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.
Flags Affected: None Flags Affected: None
CPU mode: RM,PM,VM CPU mode: RM,PM,VM
+++++++++++++++++++++++ IBTS r/m16,AX,CL,r16
Physical Form: IBTS r/m16,AX,CL,r16 IBTS r/m32,EAX,CL,r32
IBTS r/m32,EAX,CL,r32 COP (Code of Operation): 0FH A7H
COP (Code of Operation) : 0FH A7H
Clocks: IBTS Clocks: IBTS
80386: 12/19 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 CPU: 80386 step A0-B0 only
Type of Instruction: User Type of Instruction: User
Instruction: XBTS dest,base,bitoffset,len Instruction: XBTS dst,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.
Flags Affected: None Flags Affected: None
CPU mode: RM,PM,VM CPU mode: RM,PM,VM
+++++++++++++++++++++++ XBTS r16,r/m16,AX,CL
Physical Form: XBTS r16,r/m16,AX,CL
XBTS r32,r/m32,EAX,CL XBTS r32,r/m32,EAX,CL
COP (Code of Operation) : 0FH A6H COP (Code of Operation): 0FH A6H
Clocks: XBTS Clocks: XBTS
80386: 6/13 80386: 6/13

View file

@ -327,25 +327,25 @@ if (DEBUGGER) {
FCOM: 40, FCOMP: 41, FDIV: 42, FDIVR: 43, FIADD: 44, FICOM: 45, FICOMP: 46, FIDIV: 47, 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, 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, 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, FS: 64, FST: 65, FSTP: 66, FSUB: 67, FSUBR: 68, GS: 69, HLT: 70, IBTS: 71,
IMUL: 72, IN: 73, INC: 74, INS: 75, INT: 76, INT3: 77, INTO: 78, IRET: 79, IDIV: 72, IMUL: 73, IN: 74, INC: 75, INS: 76, INT: 77, INT3: 78, INTO: 79,
JBE: 80, JC: 81, JCXZ: 82, JG: 83, JGE: 84, JL: 85, JLE: 86, JMP: 87, IRET: 80, JBE: 81, JC: 82, JCXZ: 83, JG: 84, JGE: 85, JL: 86, JLE: 87,
JA: 88, JNC: 89, JNO: 90, JNP: 91, JNS: 92, JNZ: 93, JO: 94, JP: 95, JMP: 88, JA: 89, JNC: 90, JNO: 91, JNP: 92, JNS: 93, JNZ: 94, JO: 95,
JS: 96, JZ: 97, LAHF: 98, LAR: 99, LDS: 100, LEA: 101, LEAVE: 102, LES: 103, JP: 96, JS: 97, JZ: 98, LAHF: 99, LAR: 100, LDS: 101, LEA: 102, LEAVE: 103,
LFS: 104, LGDT: 105, LGS: 106, LIDT: 107, LLDT: 108, LMSW: 109, LOADALL:110, LOCK: 111, LES: 104, LFS: 105, LGDT: 106, LGS: 107, LIDT: 108, LLDT: 109, LMSW: 110, LOADALL:111,
LODSB: 112, LODSW: 113, LOOP: 114, LOOPNZ: 115, LOOPZ: 116, LSL: 117, LSS: 118, LTR: 119, LOCK: 112, LODSB: 113, LODSW: 114, LOOP: 115, LOOPNZ: 116, LOOPZ: 117, LSL: 118, LSS: 119,
MOV: 120, MOVSB: 121, MOVSW: 122, MOVSX: 123, MOVZX: 124, MUL: 125, NEG: 126, NOP: 127, LTR: 120, MOV: 121, MOVSB: 122, MOVSW: 123, MOVSX: 124, MOVZX: 125, MUL: 126, NEG: 127,
NOT: 128, OR: 129, OS: 130, OUT: 131, OUTS: 132, POP: 133, POPA: 134, POPF: 135, NOP: 128, NOT: 129, OR: 130, OS: 131, OUT: 132, OUTS: 133, POP: 134, POPA: 135,
PUSHF: 136, PUSHA: 137, PUSH: 138, RCL: 139, RCR: 140, REPNZ: 141, REPZ: 142, RET: 143, POPF: 136, PUSHF: 137, PUSHA: 138, PUSH: 139, RCL: 140, RCR: 141, REPNZ: 142, REPZ: 143,
RETF: 144, ROL: 145, ROR: 146, SAHF: 147, SALC: 148, SAR: 149, SBB: 150, SCASB: 151, RET: 144, RETF: 145, ROL: 146, ROR: 147, SAHF: 148, SALC: 149, SAR: 150, SBB: 151,
SCASW: 152, SETBE: 153, SETC: 154, SETG: 155, SETGE: 156, SETL: 157, SETLE: 158, SETNBE: 159, SCASB: 152, SCASW: 153, SETBE: 154, SETC: 155, SETG: 156, SETGE: 157, SETL: 158, SETLE: 159,
SETNC: 160, SETNO: 161, SETNP: 162, SETNS: 163, SETNZ: 164, SETO: 165, SETP: 166, SETS: 167, SETNBE: 160, SETNC: 161, SETNO: 162, SETNP: 163, SETNS: 164, SETNZ: 165, SETO: 166, SETP: 167,
SETZ: 168, SGDT: 169, SHL: 170, SHLD: 171, SHR: 172, SHRD: 173, SIDT: 174, SLDT: 175, SETS: 168, SETZ: 169, SGDT: 170, SHL: 171, SHLD: 172, SHR: 173, SHRD: 174, SIDT: 175,
SMSW: 176, SS: 177, STC: 178, STD: 179, STI: 180, STOSB: 181, STOSW: 182, STR: 183, SLDT: 176, SMSW: 177, SS: 178, STC: 179, STD: 180, STI: 181, STOSB: 182, STOSW: 183,
SUB: 184, TEST: 185, VERR: 186, VERW: 187, WAIT: 188, XCHG: 189, XLAT: 190, XOR: 191, STR: 184, SUB: 185, TEST: 186, VERR: 187, VERW: 188, WAIT: 189, XBTS: 190, XCHG: 191,
GRP1B: 192, GRP1W: 193, GRP1SW: 194, GRP2B: 195, GRP2W: 196, GRP2B1: 197, GRP2W1: 198, GRP2BC: 199, XLAT: 192, XOR: 193, GRP1B: 194, GRP1W: 195, GRP1SW: 196, GRP2B: 197, GRP2W: 198, GRP2B1: 199,
GRP2WC: 200, GRP3B: 201, GRP3W: 202, GRP4B: 203, GRP4W: 204, OP0F: 205, GRP6: 206, GRP7: 207, GRP2W1: 200, GRP2BC: 201, GRP2WC: 202, GRP3B: 203, GRP3W: 204, GRP4B: 205, GRP4W: 206, OP0F: 207,
GRP8: 208 GRP6: 208, GRP7: 209, GRP8: 210
}; };
/* /*
@ -360,22 +360,23 @@ if (DEBUGGER) {
"FCOM", "FCOMP", "FDIV", "FDIVR", "FIADD", "FICOM", "FICOMP", "FIDIV", "FCOM", "FCOMP", "FDIV", "FDIVR", "FIADD", "FICOM", "FICOMP", "FIDIV",
"FIDIVR", "FILD", "FIMUL", "FIST", "FISTP", "FISUB", "FISUBR", "FLD", "FIDIVR", "FILD", "FIMUL", "FIST", "FISTP", "FISUB", "FISUBR", "FLD",
"FLDCW", "FLDENV", "FMUL", "FNSAVE", "FNSTCW", "FNSTENV","FNSTSW", "FRSTOR", "FLDCW", "FLDENV", "FMUL", "FNSAVE", "FNSTCW", "FNSTENV","FNSTSW", "FRSTOR",
"FS:", "FST", "FSTP", "FSUB", "FSUBR", "GS:", "HLT", "IDIV", "FS:", "FST", "FSTP", "FSUB", "FSUBR", "GS:", "HLT", "IBTS",
"IMUL", "IN", "INC", "INS", "INT", "INT3", "INTO", "IRET", "IDIV", "IMUL", "IN", "INC", "INS", "INT", "INT3", "INTO",
"JBE", "JC", "JCXZ", "JG", "JGE", "JL", "JLE", "JMP", "IRET", "JBE", "JC", "JCXZ", "JG", "JGE", "JL", "JLE",
"JA", "JNC", "JNO", "JNP", "JNS", "JNZ", "JO", "JP", "JMP", "JA", "JNC", "JNO", "JNP", "JNS", "JNZ", "JO",
"JS", "JZ", "LAHF", "LAR", "LDS", "LEA", "LEAVE", "LES", "JP", "JS", "JZ", "LAHF", "LAR", "LDS", "LEA", "LEAVE",
"LFS", "LGDT", "LGS", "LIDT", "LLDT", "LMSW", "LOADALL","LOCK", "LES", "LFS", "LGDT", "LGS", "LIDT", "LLDT", "LMSW", "LOADALL",
"LODSB", "LODSW", "LOOP", "LOOPNZ", "LOOPZ", "LSL", "LSS", "LTR", "LOCK", "LODSB", "LODSW", "LOOP", "LOOPNZ", "LOOPZ", "LSL", "LSS",
"MOV", "MOVSB", "MOVSW", "MOVSX", "MOVZX", "MUL", "NEG", "NOP", "LTR", "MOV", "MOVSB", "MOVSW", "MOVSX", "MOVZX", "MUL", "NEG",
"NOT", "OR", "OS:", "OUT", "OUTS", "POP", "POPA", "POPF", "NOP", "NOT", "OR", "OS:", "OUT", "OUTS", "POP", "POPA",
"PUSHF", "PUSHA", "PUSH", "RCL", "RCR", "REPNZ", "REPZ", "RET", "POPF", "PUSHF", "PUSHA", "PUSH", "RCL", "RCR", "REPNZ", "REPZ",
"RETF", "ROL", "ROR", "SAHF", "SALC", "SAR", "SBB", "SCASB", "RET", "RETF", "ROL", "ROR", "SAHF", "SALC", "SAR", "SBB",
"SCASW", "SETBE", "SETC", "SETG", "SETGE", "SETL", "SETLE", "SETNBE", "SCASB", "SCASW", "SETBE", "SETC", "SETG", "SETGE", "SETL", "SETLE",
"SETNC", "SETNO", "SETNP", "SETNS", "SETNZ", "SETO", "SETP", "SETS", "SETNBE", "SETNC", "SETNO", "SETNP", "SETNS", "SETNZ", "SETO", "SETP",
"SETZ", "SGDT", "SHL", "SHLD", "SHR", "SHRD", "SIDT", "SLDT", "SETS", "SETZ", "SGDT", "SHL", "SHLD", "SHR", "SHRD", "SIDT",
"SMSW", "SS:", "STC", "STD", "STI", "STOSB", "STOSW", "STR", "SLDT", "SMSW", "SS:", "STC", "STD", "STI", "STOSB", "STOSW",
"SUB", "TEST", "VERR", "VERW", "WAIT", "XCHG", "XLAT", "XOR" "STR", "SUB", "TEST", "VERR", "VERW", "WAIT", "XBTS", "XCHG",
"XLAT", "XOR"
]; ];
Debugger.CPU_8086 = 0; 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], 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], 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], 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], 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], 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], 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],

View file

@ -44,10 +44,12 @@ var X86 = {
MODEL_80386: 80386, 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_80386_A0: (80386+0xA0),
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_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 * This constant is used to mark points in the code where the physical address being returned

View file

@ -110,8 +110,13 @@ function X86CPU(parmsCPU)
{ {
this.model = parmsCPU['model'] || X86.MODEL_8088; 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']; 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; var nCyclesDefault = 0;
switch(this.model) { switch(this.model) {
@ -812,6 +817,10 @@ X86CPU.prototype.initProcessor = function()
for (bOpcode in X86.aOps0F386) { for (bOpcode in X86.aOps0F386) {
this.aOps0F[+bOpcode] = X86.aOps0F386[bOpcode]; 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;
}
} }
} }
} }

View file

@ -683,6 +683,28 @@ X86.fnDECw = function(dst, src)
return w & this.maskData; 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) * fnSet64(lo, hi)
* *
@ -2033,11 +2055,11 @@ X86.fnMULw = function(dst, src)
this.regMDHi = (result >> 16) & 0xffff; this.regMDHi = (result >> 16) & 0xffff;
} else { } else {
X86.fnMUL32.call(this, dst, this.regEAX); 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) { if (this.regEAX == 0x0417A000 && dst == 0x00000081) {
/* /*
* In this case, the result should be 0x20FE7A000 (ie, regMDHi should be 0x2), and I'm not * Normally, the result should be 0x20FE7A000 (ie, regMDHi should be 0x2).
* sure what the typical failure would look like, so I'll just set regMDHi to 0. * 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. * 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; 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) * fnXCHGrb(dst, src)
* *

View file

@ -1166,6 +1166,32 @@ X86.opSHLDcl = function SHLDcl()
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 7); 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() * opPUSHGS()
* *

View file

@ -2952,9 +2952,10 @@ X86.opSTOSb = function STOSb()
* only EDI in the case of STOS. The other instructions mentioned below monkey with different * only EDI in the case of STOS. The other instructions mentioned below monkey with different
* registers, so read the errata carefully. * 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)) { if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE) != (this.getByte(this.regLIP) != X86.OPCODE.AS)) {
maskAddr ^= (0xffff0000|0); maskAddr ^= (0xffff0000|0);
} }