Scaffolding for 32-bit ModRM decoding

This commit is contained in:
Jeff Parsons 2015-01-20 22:13:40 -08:00 committed by jeffpar
commit 7cdf097c8d
9 changed files with 22819 additions and 2522 deletions

View file

@ -75,6 +75,9 @@ var w, sError = "";
var fGenMods = true;
var sEAFuncs = "";
var aBase = ["EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"];
var aIndex = ["EAX", "ECX", "EDX", "EBX", "none", "EBP", "ESI", "EDI"];
if (!fGenMods) {
var sOps = "", cOps = 0;
@ -256,11 +259,37 @@ else {
}
}
sContainer = "X86ModSIB" + ".aOpModSIB";
print(sContainer + " = [");
for (var sib = 0x00; sib <= 0xff && !sError; sib++) {
genSIB(sib);
}
print("];\n");
if (sEAFuncs) {
print("var X86Mods = {\n" + sEAFuncs + "};\n");
}
}
function genSIB(sib) {
var scale = (sib >> 6);
var index = (sib >> 3) & 0x7;
var base = (sib & 0x7);
var sFunc = "opModSIB" + toHex(sib, 2);
print(" /**");
print(" * " + sFunc + "(): scale=" + toBin(scale, 2) + " (" + toHex(1 << scale, 1) + ") index=" + toBin(index, 3) + " (" + aIndex[index] + ") base=" + toBin(base, 3) + " (" + (base == 5? "mod? EBP : disp32)" : aBase[base] + ")"));
print(" *");
print(" * @this {X86CPU}");
print(" * @param {number} mod");
print(" */");
print(" function " + sFunc + "(mod) {");
var sBase = (base == 5? "(mod? this.reg" + aBase[base] + " : this.getIPWord())" : "this.reg" + aBase[base]);
if (index != 4) sBase += " + (this.reg" + (aIndex[index] + " << " + scale) + ")";
print(" return " + sBase + ";");
print(" }" + (sib < 255? "," : ""));
}
function genMode(a, d, w, mrm, sGroup, sRO) {
var mod = (mrm >> 6);
var reg = (mrm >> 3) & 0x7;
@ -680,7 +709,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
nCycles = "this.CYCLES.nEACyclesBase";
break;
case 4:
sModAddr = "this.getSIB()";
sModAddr = "this.getSIB(0)";
sModFunc = "SIB";
nCycles = "this.CYCLES.nEACyclesBase";
break;
@ -727,7 +756,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
nCycles = "this.CYCLES.nEACyclesBaseDisp";
break;
case 4:
sModAddr = "this.getSIB() + this.getIPDisp()";
sModAddr = "this.getSIB(1) + this.getIPDisp()";
sModFunc = "SIBD8";
nCycles = "this.CYCLES.nEACyclesBaseDisp";
break;
@ -774,7 +803,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
nCycles = "this.CYCLES.nEACyclesBaseDisp";
break;
case 4:
sModAddr = "this.getSIB() + this.getIPWord()";
sModAddr = "this.getSIB(2) + this.getIPWord()";
sModFunc = "SIBD32";
nCycles = "this.CYCLES.nEACyclesBaseDisp";
break;
@ -917,7 +946,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
return null;
}
sOpMod = "opMod" + aOpPrefix[w] + aAddrPrefix[a] + (sGroup? sGroup + (sRO? sRO : "") : aDst[d]) + toHex(mrm, 2);
sOpMod = "opMod" + aAddrPrefix[a] + (sGroup? sGroup + (sRO? sRO : "") : aDst[d]) + aSize[w] + toHex(mrm, 2);
var sTemp = aSize[w].charAt(0).toLowerCase();
@ -926,7 +955,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
* Use this to generate ModRM decoders that accept an array (ie, "group") of functions, and pass along an implied argument as well
*/
if (sRO && reg != 7) {
sOpMod = "opMod" + aSize[w] + aAddrPrefix[a] + (sGroup? sGroup : aDst[d]) + toHex(mrm, 2);
sOpMod = "opMod" + aAddrPrefix[a] + (sGroup? sGroup : aDst[d]) + aSize[w] + toHex(mrm, 2);
return sOpMod;
}
@ -1023,7 +1052,7 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
if (mod == 3 && !d) {
var mrmPrime = (mod << 6) | (r_m << 3) | reg;
print(" X86Mod" + aOpPrefix[w] + aAddrPrefix[a] + ".aOpModReg[0x" + toHex(mrmPrime, 2) + "],");
sOpMod = "opMod" + aOpPrefix[w] + aAddrPrefix[a] + aDst[1] + toHex(mrmPrime, 2);
sOpMod = "opMod" + aAddrPrefix[a] + aDst[1] + aSize[w] + toHex(mrmPrime, 2);
return sOpMod;
}

View file

@ -20,6 +20,7 @@
"FATARRAYS": true,
"TYPEDARRAYS": true,
"SAMPLER": true,
"BACKTRACK": true,
"Component": true,
"State": true,
"Bus": true,
@ -43,7 +44,11 @@
"X86CPU": true,
"X86Grps": true,
"X86Help": true,
"X86Mods": true,
"X86ModB": true,
"X86ModW": true,
"X86ModB32": true,
"X86ModW32": true,
"X86ModSIB": true,
"X86OpXX": true,
"X86Op0F": true,
"str": true,

View file

@ -46,6 +46,9 @@ if (typeof module !== 'undefined') {
var X86Help = require("./x86help");
var X86ModB = require("./x86modb");
var X86ModW = require("./x86modw");
var X86ModB32 = require("./x86modb32");
var X86ModW32 = require("./x86modw32");
var X86ModSIB = require("./x86modsib");
var X86OpXX = require("./x86opxx");
var X86Op0F = require("./x86op0f");
}
@ -2318,7 +2321,7 @@ X86CPU.prototype.getIPByte = function()
{
var b = (PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP));
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & 0xffff); // this.advanceIP(1)
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & 0xffff); // this.advanceIP(1)
return b;
};
@ -2332,7 +2335,7 @@ X86CPU.prototype.getIPDisp = function()
{
var b = ((PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP)) << 24) >> 24;
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & 0xffff); // this.advanceIP(1)
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & 0xffff); // this.advanceIP(1)
return b & 0xffff;
};
@ -2349,10 +2352,24 @@ X86CPU.prototype.getIPWord = function()
this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMemHi);
}
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 2) & 0xffff); // this.advanceIP(2)
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 2) & 0xffff); // this.advanceIP(2)
return w;
};
/**
* getSIB(mod)
*
* @this {X86CPU}
* @param {number} mod
* @return {number}
*/
X86CPU.prototype.getSIB = function(mod)
{
var b = PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP);
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
return X86ModSIB.aOpModSIB[b].call(this, mod);
};
/**
* popWord()
*

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff