For research I'm building a basic x86-64 emulator in Node.js, like so:
const registerContainers = {
GPR: [],
}
for (let i = 0; i < 16; i++) {
registerContainers.GPR.push(new Uint8Array(8))
}
const registers = {}
class Register {
constructor(name, container, offset, bytes){
registers[name] = this
this.container = container
this.bytes = bytes
this.offset = offset
}
read(){
if (this.bytes === this.container.byteLength) return this.container
else return this.container.subarray(this.offset, this.container.length)
}
set(value){
this.container.set(value, this.offset)
}
}
new Register('rax', registerContainers.GPR[0], 0, 8) // Register A Extended
new Register('eax', registerContainers.GPR[0], 4, 4)
new Register('ax', registerContainers.GPR[0], 6, 2)
new Register('ah', registerContainers.GPR[0], 6, 1)
new Register('al', registerContainers.GPR[0], 7, 1)
new Register('rbx', registerContainers.GPR[1], 0, 8) // Register B Extended
new Register('ebx', registerContainers.GPR[1], 4, 4)
new Register('bx', registerContainers.GPR[1], 6, 2)
new Register('bh', registerContainers.GPR[1], 6, 1)
new Register('bl', registerContainers.GPR[1], 7, 1)
// ... and so on ...
console.log('registers', registers)
console.log('registerContainers', registerContainers)
registers.eax.set(Uint8Array.from([0x1f, 0x1f, 0x1f, 0x1f]))
console.log('updated GPR', registerContainers.GPR[0])
But the challenge I'm of course faced with is that JavaScript doesn't normally play nice with 64 bit math. My next task is to make an ALU class which performs all the possible math operations between any two registers on x86-64 architecture. I assume that 64 bit math problem will hold true for trying to use them with > 32 bit TypedArrays as operands, right?
In the MDN documentation for bitwise operators it says:
Bitwise operators treat their operands as a set of 32 bits (zeros and ones) and return standard JavaScript numerical values.
So I believe doing registerContainers.GPR[0] ^ registerContainers.GPR[1]
in the context of the above code would not perform proper math. Correct?
What I tried:
I saw Atomics
as being a native module in JS which supports shared but also unshared memory bitwise operations. However I don't see a statement in the docs about any maximum math size requirements.
Rather than trial and error, I thought I should just ask: What's the proper way to handle bitwise operations between >32 bit typed arrays in JavaScript?