How Can I Properly Add These Two Simulated General Purpose Registers In Javascript?
Solution 1:
Don't make it so complicated. joinArrayBuffers
and padArrayBufferTo64
are very inefficient, notice that buffers and typed arrays have quite some overhead in JS - they are designed to hold large binary data, not individual values, and you should try to create them once and only read/write to them afterwards.
Instead of trying to use BigUint64Array
for all your operands, and moving around buffers, I would recommend to use the appropriately sized typed arrays for your smaller registers, and just cast the number to a bigint after accessing the array (if you need bigints for all your ALU operations at all - a 32 bit ALU is probably much more efficient to implement).
const gprBuffer = newArrayBuffer(16 * 8);
classRegister {
constructor(type, offset) {
this.container = newtype(gprBuffer, offset, 1);
this.byteArray = newUint8Array(gprBuffer, offset, type.BYTES_PER_ELEMENT);
}
}
classNumberRegisterextendsRegister {
constructor(type, offset) {
super(type, offset);
this.mod = 2n ** BigInt(8 * type.BYTES_PER_ELEMENT);
}
read() {
returnBigInt(this.container[0]);
}
write(val) {
this.container[0] = Number(val % this.mod);
}
}
classBigIntRegisterextendsRegister {
constructor(type, offset) {
console.assert(type == BigUint64Array);
super(type, offset);
}
read() {
returnthis.container[0];
}
write(val) {
this.container[0] = val;
}
}
functionmakeRegister(base, bitsize, byteoffset) {
const arrayType = {8: Uint8Array, 16: Uint16Array, 32: Uint32Array, 64: BigUint64Array}[bitsize];
const registerType = bitsize > 53 ? BigIntRegister : NumberRegisterreturnnewregisterType(arrayType, base * 8 + byteoffset);
}
const registers = {
rax: makeRegister(0, 64, 0),
eax: makeRegister(0, 32, 4),
ax: makeRegister(0, 16, 6),
ah: makeRegister(0, 8, 6),
al: makeRegister(0, 8, 7),
rbx: makeRegister(1, 64, 0),
ebx: makeRegister(1, 32, 4),
bx: makeRegister(1, 16, 6),
bh: makeRegister(1, 8, 6),
bl: makeRegister(1, 8, 7),
// …
};
console.log(registers)
However, notice that typed arrays have arbitrary endianness, which you probably don't want for an emulator. Instead, consider using a (single) DataView
where you control endianness, and can use different methods to write single values into your gprBuffer
at arbitrary offsets.
Post a Comment for "How Can I Properly Add These Two Simulated General Purpose Registers In Javascript?"