@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.
- package/LICENSE +22 -0
- package/LICENSE.MIT +22 -0
- package/Readme.md +237 -0
- package/dist/v86.browser.js +26666 -0
- package/dist/v86.browser.js.map +7 -0
- package/dist/v86.js +26632 -0
- package/dist/v86.js.map +7 -0
- package/gen/generate_analyzer.ts +512 -0
- package/gen/generate_interpreter.ts +522 -0
- package/gen/generate_jit.ts +624 -0
- package/gen/rust_ast.ts +107 -0
- package/gen/util.ts +35 -0
- package/gen/x86_table.ts +1836 -0
- package/lib/9p.ts +1547 -0
- package/lib/filesystem.ts +1879 -0
- package/lib/marshall.ts +168 -0
- package/lib/softfloat/softfloat.c +32501 -0
- package/lib/zstd/zstddeclib.c +13520 -0
- package/package.json +75 -0
- package/src/acpi.ts +267 -0
- package/src/browser/dummy_screen.ts +106 -0
- package/src/browser/fake_network.ts +1771 -0
- package/src/browser/fetch_network.ts +361 -0
- package/src/browser/filestorage.ts +124 -0
- package/src/browser/inbrowser_network.ts +57 -0
- package/src/browser/keyboard.ts +564 -0
- package/src/browser/main.ts +3415 -0
- package/src/browser/mouse.ts +255 -0
- package/src/browser/network.ts +142 -0
- package/src/browser/print_stats.ts +336 -0
- package/src/browser/screen.ts +978 -0
- package/src/browser/serial.ts +316 -0
- package/src/browser/speaker.ts +1223 -0
- package/src/browser/starter.ts +1688 -0
- package/src/browser/wisp_network.ts +332 -0
- package/src/browser/worker_bus.ts +64 -0
- package/src/buffer.ts +652 -0
- package/src/bus.ts +78 -0
- package/src/const.ts +128 -0
- package/src/cpu.ts +2891 -0
- package/src/dma.ts +474 -0
- package/src/elf.ts +251 -0
- package/src/floppy.ts +1778 -0
- package/src/ide.ts +3455 -0
- package/src/io.ts +504 -0
- package/src/iso9660.ts +317 -0
- package/src/kernel.ts +250 -0
- package/src/lib.ts +645 -0
- package/src/log.ts +149 -0
- package/src/main.ts +199 -0
- package/src/ne2k.ts +1589 -0
- package/src/pci.ts +815 -0
- package/src/pit.ts +406 -0
- package/src/ps2.ts +820 -0
- package/src/rtc.ts +537 -0
- package/src/rust/analysis.rs +101 -0
- package/src/rust/codegen.rs +2660 -0
- package/src/rust/config.rs +3 -0
- package/src/rust/control_flow.rs +425 -0
- package/src/rust/cpu/apic.rs +658 -0
- package/src/rust/cpu/arith.rs +1207 -0
- package/src/rust/cpu/call_indirect.rs +2 -0
- package/src/rust/cpu/cpu.rs +4501 -0
- package/src/rust/cpu/fpu.rs +923 -0
- package/src/rust/cpu/global_pointers.rs +112 -0
- package/src/rust/cpu/instructions.rs +2486 -0
- package/src/rust/cpu/instructions_0f.rs +5261 -0
- package/src/rust/cpu/ioapic.rs +316 -0
- package/src/rust/cpu/memory.rs +351 -0
- package/src/rust/cpu/misc_instr.rs +613 -0
- package/src/rust/cpu/mod.rs +16 -0
- package/src/rust/cpu/modrm.rs +133 -0
- package/src/rust/cpu/pic.rs +402 -0
- package/src/rust/cpu/sse_instr.rs +361 -0
- package/src/rust/cpu/string.rs +701 -0
- package/src/rust/cpu/vga.rs +175 -0
- package/src/rust/cpu_context.rs +69 -0
- package/src/rust/dbg.rs +98 -0
- package/src/rust/gen/analyzer.rs +3807 -0
- package/src/rust/gen/analyzer0f.rs +3992 -0
- package/src/rust/gen/interpreter.rs +4447 -0
- package/src/rust/gen/interpreter0f.rs +5404 -0
- package/src/rust/gen/jit.rs +5080 -0
- package/src/rust/gen/jit0f.rs +5547 -0
- package/src/rust/gen/mod.rs +14 -0
- package/src/rust/jit.rs +2443 -0
- package/src/rust/jit_instructions.rs +7881 -0
- package/src/rust/js_api.rs +6 -0
- package/src/rust/leb.rs +46 -0
- package/src/rust/lib.rs +29 -0
- package/src/rust/modrm.rs +330 -0
- package/src/rust/opstats.rs +249 -0
- package/src/rust/page.rs +15 -0
- package/src/rust/paging.rs +25 -0
- package/src/rust/prefix.rs +15 -0
- package/src/rust/profiler.rs +155 -0
- package/src/rust/regs.rs +38 -0
- package/src/rust/softfloat.rs +286 -0
- package/src/rust/state_flags.rs +27 -0
- package/src/rust/wasmgen/mod.rs +2 -0
- package/src/rust/wasmgen/wasm_builder.rs +1047 -0
- package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
- package/src/rust/zstd.rs +105 -0
- package/src/sb16.ts +1928 -0
- package/src/state.ts +359 -0
- package/src/uart.ts +472 -0
- package/src/vga.ts +2791 -0
- package/src/virtio.ts +1756 -0
- package/src/virtio_balloon.ts +273 -0
- package/src/virtio_console.ts +372 -0
- 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
|
+
}
|