@aptre/v86 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSE.MIT +22 -0
  3. package/Readme.md +237 -0
  4. package/dist/v86.browser.js +26666 -0
  5. package/dist/v86.browser.js.map +7 -0
  6. package/dist/v86.js +26632 -0
  7. package/dist/v86.js.map +7 -0
  8. package/gen/generate_analyzer.ts +512 -0
  9. package/gen/generate_interpreter.ts +522 -0
  10. package/gen/generate_jit.ts +624 -0
  11. package/gen/rust_ast.ts +107 -0
  12. package/gen/util.ts +35 -0
  13. package/gen/x86_table.ts +1836 -0
  14. package/lib/9p.ts +1547 -0
  15. package/lib/filesystem.ts +1879 -0
  16. package/lib/marshall.ts +168 -0
  17. package/lib/softfloat/softfloat.c +32501 -0
  18. package/lib/zstd/zstddeclib.c +13520 -0
  19. package/package.json +75 -0
  20. package/src/acpi.ts +267 -0
  21. package/src/browser/dummy_screen.ts +106 -0
  22. package/src/browser/fake_network.ts +1771 -0
  23. package/src/browser/fetch_network.ts +361 -0
  24. package/src/browser/filestorage.ts +124 -0
  25. package/src/browser/inbrowser_network.ts +57 -0
  26. package/src/browser/keyboard.ts +564 -0
  27. package/src/browser/main.ts +3415 -0
  28. package/src/browser/mouse.ts +255 -0
  29. package/src/browser/network.ts +142 -0
  30. package/src/browser/print_stats.ts +336 -0
  31. package/src/browser/screen.ts +978 -0
  32. package/src/browser/serial.ts +316 -0
  33. package/src/browser/speaker.ts +1223 -0
  34. package/src/browser/starter.ts +1688 -0
  35. package/src/browser/wisp_network.ts +332 -0
  36. package/src/browser/worker_bus.ts +64 -0
  37. package/src/buffer.ts +652 -0
  38. package/src/bus.ts +78 -0
  39. package/src/const.ts +128 -0
  40. package/src/cpu.ts +2891 -0
  41. package/src/dma.ts +474 -0
  42. package/src/elf.ts +251 -0
  43. package/src/floppy.ts +1778 -0
  44. package/src/ide.ts +3455 -0
  45. package/src/io.ts +504 -0
  46. package/src/iso9660.ts +317 -0
  47. package/src/kernel.ts +250 -0
  48. package/src/lib.ts +645 -0
  49. package/src/log.ts +149 -0
  50. package/src/main.ts +199 -0
  51. package/src/ne2k.ts +1589 -0
  52. package/src/pci.ts +815 -0
  53. package/src/pit.ts +406 -0
  54. package/src/ps2.ts +820 -0
  55. package/src/rtc.ts +537 -0
  56. package/src/rust/analysis.rs +101 -0
  57. package/src/rust/codegen.rs +2660 -0
  58. package/src/rust/config.rs +3 -0
  59. package/src/rust/control_flow.rs +425 -0
  60. package/src/rust/cpu/apic.rs +658 -0
  61. package/src/rust/cpu/arith.rs +1207 -0
  62. package/src/rust/cpu/call_indirect.rs +2 -0
  63. package/src/rust/cpu/cpu.rs +4501 -0
  64. package/src/rust/cpu/fpu.rs +923 -0
  65. package/src/rust/cpu/global_pointers.rs +112 -0
  66. package/src/rust/cpu/instructions.rs +2486 -0
  67. package/src/rust/cpu/instructions_0f.rs +5261 -0
  68. package/src/rust/cpu/ioapic.rs +316 -0
  69. package/src/rust/cpu/memory.rs +351 -0
  70. package/src/rust/cpu/misc_instr.rs +613 -0
  71. package/src/rust/cpu/mod.rs +16 -0
  72. package/src/rust/cpu/modrm.rs +133 -0
  73. package/src/rust/cpu/pic.rs +402 -0
  74. package/src/rust/cpu/sse_instr.rs +361 -0
  75. package/src/rust/cpu/string.rs +701 -0
  76. package/src/rust/cpu/vga.rs +175 -0
  77. package/src/rust/cpu_context.rs +69 -0
  78. package/src/rust/dbg.rs +98 -0
  79. package/src/rust/gen/analyzer.rs +3807 -0
  80. package/src/rust/gen/analyzer0f.rs +3992 -0
  81. package/src/rust/gen/interpreter.rs +4447 -0
  82. package/src/rust/gen/interpreter0f.rs +5404 -0
  83. package/src/rust/gen/jit.rs +5080 -0
  84. package/src/rust/gen/jit0f.rs +5547 -0
  85. package/src/rust/gen/mod.rs +14 -0
  86. package/src/rust/jit.rs +2443 -0
  87. package/src/rust/jit_instructions.rs +7881 -0
  88. package/src/rust/js_api.rs +6 -0
  89. package/src/rust/leb.rs +46 -0
  90. package/src/rust/lib.rs +29 -0
  91. package/src/rust/modrm.rs +330 -0
  92. package/src/rust/opstats.rs +249 -0
  93. package/src/rust/page.rs +15 -0
  94. package/src/rust/paging.rs +25 -0
  95. package/src/rust/prefix.rs +15 -0
  96. package/src/rust/profiler.rs +155 -0
  97. package/src/rust/regs.rs +38 -0
  98. package/src/rust/softfloat.rs +286 -0
  99. package/src/rust/state_flags.rs +27 -0
  100. package/src/rust/wasmgen/mod.rs +2 -0
  101. package/src/rust/wasmgen/wasm_builder.rs +1047 -0
  102. package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
  103. package/src/rust/zstd.rs +105 -0
  104. package/src/sb16.ts +1928 -0
  105. package/src/state.ts +359 -0
  106. package/src/uart.ts +472 -0
  107. package/src/vga.ts +2791 -0
  108. package/src/virtio.ts +1756 -0
  109. package/src/virtio_balloon.ts +273 -0
  110. package/src/virtio_console.ts +372 -0
  111. package/src/virtio_net.ts +326 -0
@@ -0,0 +1,361 @@
1
+ use crate::cpu::cpu::*;
2
+ use crate::cpu::global_pointers::mxcsr;
3
+
4
+ pub unsafe fn mov_r_m64(addr: i32, r: i32) {
5
+ // mov* m64, mm
6
+ let data = read_mmx64s(r);
7
+ return_on_pagefault!(safe_write64(addr, data));
8
+ transition_fpu_to_mmx();
9
+ }
10
+ pub unsafe fn movl_r128_m64(addr: i32, r: i32) {
11
+ // mov* m64, xmm
12
+ let data = read_xmm64s(r);
13
+ return_on_pagefault!(safe_write64(addr, data));
14
+ }
15
+ pub unsafe fn mov_r_r128(r1: i32, r2: i32) {
16
+ // mov* xmm, xmm
17
+ let data = read_xmm128s(r2);
18
+ write_xmm_reg128(r1, data);
19
+ }
20
+ pub unsafe fn mov_r_m128(addr: i32, r: i32) {
21
+ // mov* m128, xmm
22
+ let data = read_xmm128s(r);
23
+ return_on_pagefault!(safe_write128(addr, data));
24
+ }
25
+ pub unsafe fn mov_rm_r128(source: reg128, r: i32) {
26
+ // mov* xmm, xmm/m128
27
+ write_xmm_reg128(r, source);
28
+ }
29
+ pub unsafe fn movh_r128_m64(addr: i32, r: i32) {
30
+ // movhp* m64, xmm
31
+ let data = read_xmm128s(r);
32
+ return_on_pagefault!(safe_write64(addr, data.u64[1]));
33
+ }
34
+
35
+ pub unsafe fn pand_r128(source: reg128, r: i32) {
36
+ // pand xmm, xmm/m128
37
+ // XXX: Aligned access or #gp
38
+ let destination = read_xmm128s(r);
39
+ let mut result = reg128 { i8: [0; 16] };
40
+ result.u64[0] = source.u64[0] & destination.u64[0];
41
+ result.u64[1] = source.u64[1] & destination.u64[1];
42
+ write_xmm_reg128(r, result);
43
+ }
44
+ pub unsafe fn pandn_r128(source: reg128, r: i32) {
45
+ // pandn xmm, xmm/m128
46
+ // XXX: Aligned access or #gp
47
+ let destination = read_xmm128s(r);
48
+ let mut result = reg128 { i8: [0; 16] };
49
+ result.u64[0] = source.u64[0] & !destination.u64[0];
50
+ result.u64[1] = source.u64[1] & !destination.u64[1];
51
+ write_xmm_reg128(r, result);
52
+ }
53
+ pub unsafe fn pxor_r128(source: reg128, r: i32) {
54
+ // pxor xmm, xmm/m128
55
+ // XXX: Aligned access or #gp
56
+ let destination = read_xmm128s(r);
57
+ let mut result = reg128 { i8: [0; 16] };
58
+ result.u64[0] = source.u64[0] ^ destination.u64[0];
59
+ result.u64[1] = source.u64[1] ^ destination.u64[1];
60
+ write_xmm_reg128(r, result);
61
+ }
62
+ pub unsafe fn por_r128(source: reg128, r: i32) {
63
+ // por xmm, xmm/m128
64
+ // XXX: Aligned access or #gp
65
+ let destination = read_xmm128s(r);
66
+ let mut result = reg128 { i8: [0; 16] };
67
+ result.u64[0] = source.u64[0] | destination.u64[0];
68
+ result.u64[1] = source.u64[1] | destination.u64[1];
69
+ write_xmm_reg128(r, result);
70
+ }
71
+
72
+ pub unsafe fn psrlw_r64(r: i32, shift: u64) {
73
+ // psrlw mm, {shift}
74
+ let destination: [u16; 4] = std::mem::transmute(read_mmx64s(r));
75
+ let shift = if shift > 15 { 16 } else { shift };
76
+ let mut result = [0; 4];
77
+ for i in 0..4 {
78
+ result[i] = ((destination[i] as u32) >> shift) as u16
79
+ }
80
+ write_mmx_reg64(r, std::mem::transmute(result));
81
+ transition_fpu_to_mmx();
82
+ }
83
+ pub unsafe fn psraw_r64(r: i32, shift: u64) {
84
+ // psraw mm, {shift}
85
+ let destination: [i16; 4] = std::mem::transmute(read_mmx64s(r));
86
+ let shift = if shift > 15 { 16 } else { shift };
87
+ let mut result = [0; 4];
88
+ for i in 0..4 {
89
+ result[i] = (destination[i] as i32 >> shift) as i16
90
+ }
91
+ write_mmx_reg64(r, std::mem::transmute(result));
92
+ transition_fpu_to_mmx();
93
+ }
94
+ pub unsafe fn psllw_r64(r: i32, shift: u64) {
95
+ // psllw mm, {shift}
96
+ let destination: [i16; 4] = std::mem::transmute(read_mmx64s(r));
97
+ let mut result = [0; 4];
98
+ if shift <= 15 {
99
+ for i in 0..4 {
100
+ result[i] = destination[i] << shift
101
+ }
102
+ }
103
+ write_mmx_reg64(r, std::mem::transmute(result));
104
+ transition_fpu_to_mmx();
105
+ }
106
+ pub unsafe fn psrld_r64(r: i32, shift: u64) {
107
+ // psrld mm, {shift}
108
+ let destination: [u32; 2] = std::mem::transmute(read_mmx64s(r));
109
+ let mut result = [0; 2];
110
+ if shift <= 31 {
111
+ for i in 0..2 {
112
+ result[i] = destination[i] >> shift;
113
+ }
114
+ }
115
+ write_mmx_reg64(r, std::mem::transmute(result));
116
+ transition_fpu_to_mmx();
117
+ }
118
+ pub unsafe fn psrad_r64(r: i32, shift: u64) {
119
+ // psrad mm, {shift}
120
+ let destination: [i32; 2] = std::mem::transmute(read_mmx64s(r));
121
+ let shift = if shift > 31 { 31 } else { shift };
122
+ let mut result = [0; 2];
123
+ for i in 0..2 {
124
+ result[i] = destination[i] >> shift;
125
+ }
126
+ write_mmx_reg64(r, std::mem::transmute(result));
127
+ transition_fpu_to_mmx();
128
+ }
129
+ pub unsafe fn pslld_r64(r: i32, shift: u64) {
130
+ // pslld mm, {shift}
131
+ let destination: [i32; 2] = std::mem::transmute(read_mmx64s(r));
132
+ let mut result = [0; 2];
133
+ if shift <= 31 {
134
+ for i in 0..2 {
135
+ result[i] = destination[i] << shift;
136
+ }
137
+ }
138
+ write_mmx_reg64(r, std::mem::transmute(result));
139
+ transition_fpu_to_mmx();
140
+ }
141
+ pub unsafe fn psrlq_r64(r: i32, shift: u64) {
142
+ // psrlq mm, {shift}
143
+ let destination = read_mmx64s(r);
144
+ let mut result = 0;
145
+ if shift <= 63 {
146
+ result = destination >> shift
147
+ }
148
+ write_mmx_reg64(r, result);
149
+ transition_fpu_to_mmx();
150
+ }
151
+ pub unsafe fn psllq_r64(r: i32, shift: u64) {
152
+ // psllq mm, {shift}
153
+ let destination = read_mmx64s(r);
154
+ let mut result = 0;
155
+ if shift <= 63 {
156
+ result = destination << shift
157
+ }
158
+ write_mmx_reg64(r, result);
159
+ transition_fpu_to_mmx();
160
+ }
161
+ pub unsafe fn psrlw_r128(r: i32, shift: u64) {
162
+ // psrlw xmm, {shift}
163
+ let destination = read_xmm128s(r);
164
+ let mut dword0 = 0;
165
+ let mut dword1 = 0;
166
+ let mut dword2 = 0;
167
+ let mut dword3 = 0;
168
+ if shift <= 15 {
169
+ dword0 = destination.u16[0] as i32 >> shift | destination.u16[1] as i32 >> shift << 16;
170
+ dword1 = destination.u16[2] as i32 >> shift | destination.u16[3] as i32 >> shift << 16;
171
+ dword2 = destination.u16[4] as i32 >> shift | destination.u16[5] as i32 >> shift << 16;
172
+ dword3 = destination.u16[6] as i32 >> shift | destination.u16[7] as i32 >> shift << 16
173
+ }
174
+ write_xmm128(r, dword0, dword1, dword2, dword3);
175
+ }
176
+ pub unsafe fn psraw_r128(r: i32, shift: u64) {
177
+ // psraw xmm, {shift}
178
+ let destination = read_xmm128s(r);
179
+ let shift_clamped = (if shift > 15 { 16 } else { shift as u32 }) as i32;
180
+ let dword0 = destination.i16[0] as i32 >> shift_clamped & 0xFFFF
181
+ | destination.i16[1] as i32 >> shift_clamped << 16;
182
+ let dword1 = destination.i16[2] as i32 >> shift_clamped & 0xFFFF
183
+ | destination.i16[3] as i32 >> shift_clamped << 16;
184
+ let dword2 = destination.i16[4] as i32 >> shift_clamped & 0xFFFF
185
+ | destination.i16[5] as i32 >> shift_clamped << 16;
186
+ let dword3 = destination.i16[6] as i32 >> shift_clamped & 0xFFFF
187
+ | destination.i16[7] as i32 >> shift_clamped << 16;
188
+ write_xmm128(r, dword0, dword1, dword2, dword3);
189
+ }
190
+ pub unsafe fn psllw_r128(r: i32, shift: u64) {
191
+ // psllw xmm, {shift}
192
+ let destination = read_xmm128s(r);
193
+ let mut dword0 = 0;
194
+ let mut dword1 = 0;
195
+ let mut dword2 = 0;
196
+ let mut dword3 = 0;
197
+ if shift <= 15 {
198
+ dword0 = (destination.u16[0] as i32) << shift & 0xFFFF
199
+ | (destination.u16[1] as i32) << shift << 16;
200
+ dword1 = (destination.u16[2] as i32) << shift & 0xFFFF
201
+ | (destination.u16[3] as i32) << shift << 16;
202
+ dword2 = (destination.u16[4] as i32) << shift & 0xFFFF
203
+ | (destination.u16[5] as i32) << shift << 16;
204
+ dword3 = (destination.u16[6] as i32) << shift & 0xFFFF
205
+ | (destination.u16[7] as i32) << shift << 16
206
+ }
207
+ write_xmm128(r, dword0, dword1, dword2, dword3);
208
+ }
209
+ pub unsafe fn psrld_r128(r: i32, shift: u64) {
210
+ // psrld xmm, {shift}
211
+ let destination = read_xmm128s(r);
212
+ let mut dword0 = 0;
213
+ let mut dword1 = 0;
214
+ let mut dword2 = 0;
215
+ let mut dword3 = 0;
216
+ if shift <= 31 {
217
+ dword0 = (destination.u32[0] >> shift) as i32;
218
+ dword1 = (destination.u32[1] >> shift) as i32;
219
+ dword2 = (destination.u32[2] >> shift) as i32;
220
+ dword3 = (destination.u32[3] >> shift) as i32
221
+ }
222
+ write_xmm128(r, dword0, dword1, dword2, dword3);
223
+ }
224
+ pub unsafe fn psrad_r128(r: i32, shift: u64) {
225
+ // psrad xmm, {shift}
226
+ let destination = read_xmm128s(r);
227
+ let shift_clamped = (if shift > 31 { 31 } else { shift }) as i32;
228
+ let dword0 = destination.i32[0] >> shift_clamped;
229
+ let dword1 = destination.i32[1] >> shift_clamped;
230
+ let dword2 = destination.i32[2] >> shift_clamped;
231
+ let dword3 = destination.i32[3] >> shift_clamped;
232
+ write_xmm128(r, dword0, dword1, dword2, dword3);
233
+ }
234
+ pub unsafe fn pslld_r128(r: i32, shift: u64) {
235
+ // pslld xmm, {shift}
236
+ let destination = read_xmm128s(r);
237
+ let mut dword0 = 0;
238
+ let mut dword1 = 0;
239
+ let mut dword2 = 0;
240
+ let mut dword3 = 0;
241
+ if shift <= 31 {
242
+ dword0 = destination.i32[0] << shift;
243
+ dword1 = destination.i32[1] << shift;
244
+ dword2 = destination.i32[2] << shift;
245
+ dword3 = destination.i32[3] << shift
246
+ }
247
+ write_xmm128(r, dword0, dword1, dword2, dword3);
248
+ }
249
+ pub unsafe fn psrlq_r128(r: i32, shift: u64) {
250
+ // psrlq xmm, {shift}
251
+ let destination = read_xmm128s(r);
252
+ let mut result = reg128 { i8: [0; 16] };
253
+ if shift <= 63 {
254
+ result.u64[0] = destination.u64[0] >> shift;
255
+ result.u64[1] = destination.u64[1] >> shift
256
+ }
257
+ write_xmm_reg128(r, result);
258
+ }
259
+ pub unsafe fn psllq_r128(r: i32, shift: u64) {
260
+ // psllq xmm, {shift}
261
+ let destination = read_xmm128s(r);
262
+ let mut result = reg128 { i8: [0; 16] };
263
+ if shift <= 63 {
264
+ result.u64[0] = destination.u64[0] << shift;
265
+ result.u64[1] = destination.u64[1] << shift
266
+ }
267
+ write_xmm_reg128(r, result);
268
+ }
269
+
270
+ pub unsafe fn sse_comparison(op: i32, x: f64, y: f64) -> bool {
271
+ // TODO: Signaling
272
+ match op & 7 {
273
+ 0 => return x == y,
274
+ 1 => return x < y,
275
+ 2 => return x <= y,
276
+ 3 => return x.is_nan() || y.is_nan(),
277
+ 4 => return x != y || x.is_nan() || y.is_nan(),
278
+ 5 => return x >= y || x.is_nan() || y.is_nan(),
279
+ 6 => return x > y || x.is_nan() || y.is_nan(),
280
+ 7 => return !x.is_nan() && !y.is_nan(),
281
+ _ => {
282
+ dbg_assert!(false);
283
+ return false;
284
+ },
285
+ };
286
+ }
287
+ pub unsafe fn sse_min(x: f64, y: f64) -> f64 {
288
+ // if both x and y are 0 or x is nan, y is returned
289
+ return if x < y { x } else { y };
290
+ }
291
+ pub unsafe fn sse_max(x: f64, y: f64) -> f64 {
292
+ // if both x and y are 0 or x is nan, y is returned
293
+ return if x > y { x } else { y };
294
+ }
295
+
296
+ #[no_mangle]
297
+ pub unsafe fn sse_convert_with_truncation_f32_to_i32(x: f32) -> i32 {
298
+ let x = x.trunc();
299
+ if x >= -2147483648.0 && x < 2147483648.0 {
300
+ return x as i64 as i32;
301
+ }
302
+ else {
303
+ // TODO: Signal
304
+ return -0x80000000;
305
+ };
306
+ }
307
+ #[no_mangle]
308
+ pub unsafe fn sse_convert_f32_to_i32(x: f32) -> i32 {
309
+ let x = sse_integer_round(x as f64);
310
+ if x >= -2147483648.0 && x < 2147483648.0 {
311
+ return x as i64 as i32;
312
+ }
313
+ else {
314
+ // TODO: Signal
315
+ return -0x80000000;
316
+ };
317
+ }
318
+
319
+ #[no_mangle]
320
+ pub unsafe fn sse_convert_with_truncation_f64_to_i32(x: f64) -> i32 {
321
+ let x = x.trunc();
322
+ if x >= -2147483648.0 && x < 2147483648.0 {
323
+ return x as i64 as i32;
324
+ }
325
+ else {
326
+ // TODO: Signal
327
+ return -0x80000000;
328
+ };
329
+ }
330
+ #[no_mangle]
331
+ pub unsafe fn sse_convert_f64_to_i32(x: f64) -> i32 {
332
+ let x = sse_integer_round(x);
333
+ if x >= -2147483648.0 && x < 2147483648.0 {
334
+ return x as i64 as i32;
335
+ }
336
+ else {
337
+ // TODO: Signal
338
+ return -0x80000000;
339
+ };
340
+ }
341
+
342
+ pub unsafe fn sse_integer_round(f: f64) -> f64 {
343
+ // see fpu_integer_round
344
+ let rc = *mxcsr >> MXCSR_RC_SHIFT & 3;
345
+ if rc == 0 {
346
+ // Round to nearest, or even if equidistant
347
+ let mut rounded = f.round();
348
+ let diff = rounded - f;
349
+ if diff == 0.5 || diff == -0.5 {
350
+ rounded = 2.0 * (f * 0.5).round()
351
+ }
352
+ return rounded;
353
+ }
354
+ else if rc == 1 || rc == 3 && f > 0.0 {
355
+ // rc=3 is truncate -> floor for positive numbers
356
+ return f.floor();
357
+ }
358
+ else {
359
+ return f.ceil();
360
+ };
361
+ }