Port fpu to C
This commit is contained in:
parent
fb1cb5e800
commit
9ad9693cdd
|
@ -172,25 +172,6 @@ function V86Starter(options)
|
|||
"_mmap_write16": function(addr, value) { return cpu.mmap_write16(addr, value); },
|
||||
"_mmap_write32": function(addr, value) { return cpu.mmap_write32(addr, value); },
|
||||
|
||||
"_fpu_op_D8_reg": function() { return cpu.fpu.op_D8_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_D9_reg": function() { return cpu.fpu.op_D9_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DA_reg": function() { return cpu.fpu.op_DA_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DB_reg": function() { return cpu.fpu.op_DB_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DC_reg": function() { return cpu.fpu.op_DC_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DD_reg": function() { return cpu.fpu.op_DD_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DE_reg": function() { return cpu.fpu.op_DE_reg.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DF_reg": function() { return cpu.fpu.op_DF_reg.apply(cpu.fpu, arguments); },
|
||||
|
||||
"_fpu_op_D8_mem": function() { return cpu.fpu.op_D8_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_D9_mem": function() { return cpu.fpu.op_D9_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DA_mem": function() { return cpu.fpu.op_DA_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DB_mem": function() { return cpu.fpu.op_DB_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DC_mem": function() { return cpu.fpu.op_DC_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DD_mem": function() { return cpu.fpu.op_DD_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DE_mem": function() { return cpu.fpu.op_DE_mem.apply(cpu.fpu, arguments); },
|
||||
"_fpu_op_DF_mem": function() { return cpu.fpu.op_DF_mem.apply(cpu.fpu, arguments); },
|
||||
"_fwait": function() { return cpu.fpu.fwait(); },
|
||||
|
||||
"_int_log2": function(val) { return v86util.int_log2(val); },
|
||||
"_math_pow": function(x, y) { return Math.pow(x, y); },
|
||||
|
||||
|
@ -244,6 +225,21 @@ function V86Starter(options)
|
|||
"_get_time": () => Date.now(),
|
||||
|
||||
"_codegen_finalize": (cache_index, virt_start, start, end) => cpu.codegen_finalize(cache_index, virt_start, start, end),
|
||||
|
||||
"_atan2": Math.atan2,
|
||||
"_sin": Math.sin,
|
||||
"_cos": Math.cos,
|
||||
"_tan": Math.tan,
|
||||
"_trunc": Math.trunc,
|
||||
"_fmod": (x, y) => x % y,
|
||||
"_llvm_exp2_f64": (x) => Math.pow(2, x),
|
||||
"_log": Math.log,
|
||||
"_round": Math.round,
|
||||
};
|
||||
|
||||
const wasm_globals = {
|
||||
"Infinity": Infinity,
|
||||
"NaN": NaN,
|
||||
};
|
||||
|
||||
let wasm_file = DEBUG ? "v86-debug.wasm" : "v86.wasm";
|
||||
|
@ -259,7 +255,7 @@ function V86Starter(options)
|
|||
|
||||
v86util.load_wasm(
|
||||
wasm_file,
|
||||
{ "env": wasm_shared_funcs },
|
||||
{ "env": wasm_shared_funcs, "global" : wasm_globals },
|
||||
options["memory_size"] + INTERNAL_MEM_SIZE,
|
||||
WASM_TABLE_SIZE,
|
||||
wm => {
|
||||
|
|
52
src/cpu.js
52
src/cpu.js
|
@ -192,6 +192,29 @@ function CPU(bus, wm, codegen)
|
|||
this.reg8s = new Int8Array(this.reg32s.buffer, 4, 32);
|
||||
this.reg8 = new Uint8Array(this.reg32s.buffer, 4, 32);
|
||||
|
||||
// Why no Float80Array :-(
|
||||
this.fpu_st = new Float64Array(wm.memory.buffer, 968, 8);
|
||||
|
||||
this.fpu_stack_empty = new Int32Array(wm.memory.buffer, 816, 1);
|
||||
this.fpu_stack_empty[0] = 0xff;
|
||||
this.fpu_stack_ptr = new Uint32Array(wm.memory.buffer, 1032, 1);
|
||||
this.fpu_stack_ptr[0] = 0;
|
||||
|
||||
this.fpu_control_word = new Int32Array(wm.memory.buffer, 1036, 1);
|
||||
this.fpu_control_word[0] = 0x37F;
|
||||
this.fpu_status_word = new Int32Array(wm.memory.buffer, 1040, 1);
|
||||
this.fpu_status_word[0] = 0;
|
||||
this.fpu_ip = new Int32Array(wm.memory.buffer, 1048, 1);
|
||||
this.fpu_ip[0] = 0;
|
||||
this.fpu_ip_selector = new Int32Array(wm.memory.buffer, 1052, 1);
|
||||
this.fpu_ip_selector[0] = 0;
|
||||
this.fpu_opcode = new Int32Array(wm.memory.buffer, 1044, 1);
|
||||
this.fpu_opcode[0] = 0;
|
||||
this.fpu_dp = new Int32Array(wm.memory.buffer, 1056, 1);
|
||||
this.fpu_dp[0] = 0;
|
||||
this.fpu_dp_selector = new Int32Array(wm.memory.buffer, 1060, 1);
|
||||
this.fpu_dp_selector[0] = 0;
|
||||
|
||||
// mm0-mm7 split up into 32 bit pairs
|
||||
this.reg_mmxs = new Int32Array(wm.memory.buffer, 1064, 16);
|
||||
this.reg_mmx = new Uint32Array(this.reg_mmxs.buffer, 1064, 16);
|
||||
|
@ -211,7 +234,6 @@ function CPU(bus, wm, codegen)
|
|||
this.fw_value = new Int32Array(wm.memory.buffer, 720, 1);
|
||||
|
||||
this.io = undefined;
|
||||
this.fpu = undefined;
|
||||
|
||||
this.bus = bus;
|
||||
|
||||
|
@ -452,7 +474,6 @@ CPU.prototype.get_state = function()
|
|||
state[40] = this.sreg;
|
||||
state[41] = this.dreg;
|
||||
state[42] = this.mem8;
|
||||
state[43] = this.fpu;
|
||||
|
||||
state[45] = this.devices.virtio;
|
||||
state[46] = this.devices.apic;
|
||||
|
@ -481,6 +502,16 @@ CPU.prototype.get_state = function()
|
|||
state[65] = this.reg_mmxs;
|
||||
state[66] = this.reg_xmm32s;
|
||||
|
||||
state[67] = this.fpu_st;
|
||||
state[68] = this.fpu_stack_empty[0];
|
||||
state[69] = this.fpu_stack_ptr[0];
|
||||
state[70] = this.fpu_control_word[0];
|
||||
state[71] = this.fpu_ip[0];
|
||||
state[72] = this.fpu_ip_selector[0];
|
||||
state[73] = this.fpu_dp[0];
|
||||
state[74] = this.fpu_dp_selector[0];
|
||||
state[75] = this.fpu_opcode[0];
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
|
@ -527,7 +558,6 @@ CPU.prototype.set_state = function(state)
|
|||
this.sreg.set(state[40]);
|
||||
this.dreg.set(state[41]);
|
||||
this.mem8.set(state[42]);
|
||||
this.fpu = state[43];
|
||||
|
||||
this.devices.virtio = state[45];
|
||||
this.devices.apic = state[46];
|
||||
|
@ -556,6 +586,16 @@ CPU.prototype.set_state = function(state)
|
|||
this.reg_mmxs.set(state[65]);
|
||||
this.reg_xmm32s.set(state[66]);
|
||||
|
||||
this.fpu_st.set(state[67]);
|
||||
this.fpu_stack_empty[0] = state[68];
|
||||
this.fpu_stack_ptr[0] = state[69];
|
||||
this.fpu_control_word[0] = state[70];
|
||||
this.fpu_ip[0] = state[71];
|
||||
this.fpu_ip_selector[0] = state[72];
|
||||
this.fpu_dp[0] = state[73];
|
||||
this.fpu_dp_selector[0] = state[74];
|
||||
this.fpu_opcode[0] = state[75];
|
||||
|
||||
this.full_clear_tlb();
|
||||
// tsc_offset?
|
||||
|
||||
|
@ -849,8 +889,6 @@ CPU.prototype.init = function(settings, device_bus)
|
|||
this.devices.vga = new VGAScreen(this, device_bus,
|
||||
settings.vga_memory_size || 8 * 1024 * 1024);
|
||||
|
||||
this.fpu = new FPU(this);
|
||||
|
||||
this.devices.ps2 = new PS2(this, device_bus);
|
||||
|
||||
this.devices.uart = new UART(this, 0x3F8, device_bus);
|
||||
|
@ -1500,7 +1538,7 @@ CPU.prototype.set_cr0 = function(cr0)
|
|||
|
||||
this.cr[0] = cr0;
|
||||
|
||||
if(!this.fpu)
|
||||
if(false)
|
||||
{
|
||||
// if there's no FPU, keep emulation set
|
||||
this.cr[0] |= CR0_EM;
|
||||
|
@ -3703,7 +3741,7 @@ CPU.prototype.cpuid = function()
|
|||
ecx = 1 << 23 | 1 << 30; // popcnt, rdrand
|
||||
var vme = 0 << 1;
|
||||
if(VMWARE_HYPERVISOR_PORT) ecx |= 1 << 31; // hypervisor
|
||||
edx = (this.fpu ? 1 : 0) | // fpu
|
||||
edx = (true /* have fpu */ ? 1 : 0) | // fpu
|
||||
vme | 1 << 3 | 1 << 4 | 1 << 5 | // vme, pse, tsc, msr
|
||||
1 << 8 | 1 << 11 | 1 << 13 | 1 << 15 | // cx8, sep, pge, cmov
|
||||
1 << 23 | 1 << 24 | 1 << 25 | 1 << 26; // mmx, fxsr, sse1, sse2
|
||||
|
|
|
@ -827,6 +827,14 @@ void clear_tlb()
|
|||
memcpy_large(tlb_info, tlb_info_global, 0x100000);
|
||||
}
|
||||
|
||||
void task_switch_test()
|
||||
{
|
||||
if(cr[0] & (CR0_EM | CR0_TS))
|
||||
{
|
||||
trigger_nm();
|
||||
}
|
||||
}
|
||||
|
||||
void task_switch_test_mmx()
|
||||
{
|
||||
if(*cr & (CR0_EM | CR0_TS))
|
||||
|
|
|
@ -70,6 +70,7 @@ void write_xmm64(int32_t r, union reg64 data);
|
|||
void write_xmm128(int32_t r, int32_t i0, int32_t i1, int32_t i2, int32_t i3);
|
||||
void write_xmm_reg128(int32_t r, union reg128 data);
|
||||
void clear_tlb(void);
|
||||
void task_switch_test(void);
|
||||
void task_switch_test_mmx(void);
|
||||
int32_t read_moffs(void);
|
||||
int32_t get_real_eip(void);
|
||||
|
|
1468
src/native/fpu.c
1468
src/native/fpu.c
File diff suppressed because it is too large
Load diff
|
@ -9,3 +9,21 @@ int32_t fpu_load_status_word(void);
|
|||
void fpu_set_status_word(int32_t sw);
|
||||
void fpu_store_m80(uint32_t addr, double_t n);
|
||||
double_t fpu_load_m80(uint32_t addr);
|
||||
void fwait();
|
||||
|
||||
void fpu_op_D8_mem(int32_t, int32_t);
|
||||
void fpu_op_D8_reg(int32_t);
|
||||
void fpu_op_D9_mem(int32_t, int32_t);
|
||||
void fpu_op_D9_reg(int32_t);
|
||||
void fpu_op_DA_mem(int32_t, int32_t);
|
||||
void fpu_op_DA_reg(int32_t);
|
||||
void fpu_op_DB_mem(int32_t, int32_t);
|
||||
void fpu_op_DB_reg(int32_t);
|
||||
void fpu_op_DC_mem(int32_t, int32_t);
|
||||
void fpu_op_DC_reg(int32_t);
|
||||
void fpu_op_DD_mem(int32_t, int32_t);
|
||||
void fpu_op_DD_reg(int32_t);
|
||||
void fpu_op_DE_mem(int32_t, int32_t);
|
||||
void fpu_op_DE_reg(int32_t);
|
||||
void fpu_op_DF_mem(int32_t, int32_t);
|
||||
void fpu_op_DF_reg(int32_t);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "log.h"
|
||||
#include "arith.h"
|
||||
#include "cpu.h"
|
||||
#include "fpu.h"
|
||||
#include "shared.h"
|
||||
#include "misc_instr.h"
|
||||
#include "string.h"
|
||||
|
|
|
@ -33,24 +33,7 @@ extern void enter16(int32_t, int32_t);
|
|||
extern void enter32(int32_t, int32_t);
|
||||
extern void far_jump(int32_t, int32_t, int32_t);
|
||||
extern void far_return(int32_t, int32_t, int32_t);
|
||||
extern void fpu_op_D8_mem(int32_t, int32_t);
|
||||
extern void fpu_op_D8_reg(int32_t);
|
||||
extern void fpu_op_D9_mem(int32_t, int32_t);
|
||||
extern void fpu_op_D9_reg(int32_t);
|
||||
extern void fpu_op_DA_mem(int32_t, int32_t);
|
||||
extern void fpu_op_DA_reg(int32_t);
|
||||
extern void fpu_op_DB_mem(int32_t, int32_t);
|
||||
extern void fpu_op_DB_reg(int32_t);
|
||||
extern void fpu_op_DC_mem(int32_t, int32_t);
|
||||
extern void fpu_op_DC_reg(int32_t);
|
||||
extern void fpu_op_DD_mem(int32_t, int32_t);
|
||||
extern void fpu_op_DD_reg(int32_t);
|
||||
extern void fpu_op_DE_mem(int32_t, int32_t);
|
||||
extern void fpu_op_DE_reg(int32_t);
|
||||
extern void fpu_op_DF_mem(int32_t, int32_t);
|
||||
extern void fpu_op_DF_reg(int32_t);
|
||||
extern void full_clear_tlb(void);
|
||||
extern void fwait(void);
|
||||
extern void handle_irqs(void);
|
||||
extern void hlt_op(void);
|
||||
extern void invlpg(int32_t);
|
||||
|
@ -64,7 +47,6 @@ extern void mmap_write32(uint32_t, int32_t);
|
|||
extern void mmap_write8(uint32_t, int32_t);
|
||||
extern void popa16(void);
|
||||
extern void popa32(void);
|
||||
extern void task_switch_test(void);
|
||||
extern void todo(void);
|
||||
extern void undefined_instruction(void);
|
||||
extern void unimplemented_sse(void);
|
||||
|
|
Loading…
Reference in a new issue