Skip to main content

shape_jit/ffi/
v2_math.rs

1//! Monomorphized Typed FFI Math Functions (v2 Runtime)
2//!
3//! These functions operate on native types (f64, i64, i32) directly,
4//! eliminating NaN-boxing overhead. They will replace the generic
5//! NaN-boxed math FFI functions as the v2 runtime migration progresses.
6
7// ============================================================================
8// f64 Arithmetic
9// ============================================================================
10
11#[inline]
12pub extern "C" fn jit_add_f64(a: f64, b: f64) -> f64 {
13    a + b
14}
15
16#[inline]
17pub extern "C" fn jit_sub_f64(a: f64, b: f64) -> f64 {
18    a - b
19}
20
21#[inline]
22pub extern "C" fn jit_mul_f64(a: f64, b: f64) -> f64 {
23    a * b
24}
25
26#[inline]
27pub extern "C" fn jit_div_f64(a: f64, b: f64) -> f64 {
28    a / b
29}
30
31#[inline]
32pub extern "C" fn jit_mod_f64(a: f64, b: f64) -> f64 {
33    a % b
34}
35
36#[inline]
37pub extern "C" fn jit_neg_f64(a: f64) -> f64 {
38    -a
39}
40
41// ============================================================================
42// f64 Comparisons (return u8: 1 = true, 0 = false)
43// ============================================================================
44
45#[inline]
46pub extern "C" fn jit_cmp_lt_f64(a: f64, b: f64) -> u8 {
47    (a < b) as u8
48}
49
50#[inline]
51pub extern "C" fn jit_cmp_le_f64(a: f64, b: f64) -> u8 {
52    (a <= b) as u8
53}
54
55#[inline]
56pub extern "C" fn jit_cmp_gt_f64(a: f64, b: f64) -> u8 {
57    (a > b) as u8
58}
59
60#[inline]
61pub extern "C" fn jit_cmp_ge_f64(a: f64, b: f64) -> u8 {
62    (a >= b) as u8
63}
64
65#[inline]
66pub extern "C" fn jit_cmp_eq_f64(a: f64, b: f64) -> u8 {
67    (a == b) as u8
68}
69
70#[inline]
71pub extern "C" fn jit_cmp_ne_f64(a: f64, b: f64) -> u8 {
72    (a != b) as u8
73}
74
75// ============================================================================
76// i64 Arithmetic (wrapping to avoid UB on overflow)
77// ============================================================================
78
79#[inline]
80pub extern "C" fn jit_add_i64(a: i64, b: i64) -> i64 {
81    a.wrapping_add(b)
82}
83
84#[inline]
85pub extern "C" fn jit_sub_i64(a: i64, b: i64) -> i64 {
86    a.wrapping_sub(b)
87}
88
89#[inline]
90pub extern "C" fn jit_mul_i64(a: i64, b: i64) -> i64 {
91    a.wrapping_mul(b)
92}
93
94#[inline]
95pub extern "C" fn jit_div_i64(a: i64, b: i64) -> i64 {
96    if b == 0 {
97        0
98    } else {
99        a.wrapping_div(b)
100    }
101}
102
103#[inline]
104pub extern "C" fn jit_mod_i64(a: i64, b: i64) -> i64 {
105    if b == 0 {
106        0
107    } else {
108        a.wrapping_rem(b)
109    }
110}
111
112#[inline]
113pub extern "C" fn jit_neg_i64(a: i64) -> i64 {
114    a.wrapping_neg()
115}
116
117// ============================================================================
118// i64 Comparisons
119// ============================================================================
120
121#[inline]
122pub extern "C" fn jit_cmp_lt_i64(a: i64, b: i64) -> u8 {
123    (a < b) as u8
124}
125
126#[inline]
127pub extern "C" fn jit_cmp_le_i64(a: i64, b: i64) -> u8 {
128    (a <= b) as u8
129}
130
131#[inline]
132pub extern "C" fn jit_cmp_gt_i64(a: i64, b: i64) -> u8 {
133    (a > b) as u8
134}
135
136#[inline]
137pub extern "C" fn jit_cmp_ge_i64(a: i64, b: i64) -> u8 {
138    (a >= b) as u8
139}
140
141#[inline]
142pub extern "C" fn jit_cmp_eq_i64(a: i64, b: i64) -> u8 {
143    (a == b) as u8
144}
145
146#[inline]
147pub extern "C" fn jit_cmp_ne_i64(a: i64, b: i64) -> u8 {
148    (a != b) as u8
149}
150
151// ============================================================================
152// i32 Arithmetic (wrapping to avoid UB on overflow)
153// ============================================================================
154
155#[inline]
156pub extern "C" fn jit_add_i32(a: i32, b: i32) -> i32 {
157    a.wrapping_add(b)
158}
159
160#[inline]
161pub extern "C" fn jit_sub_i32(a: i32, b: i32) -> i32 {
162    a.wrapping_sub(b)
163}
164
165#[inline]
166pub extern "C" fn jit_mul_i32(a: i32, b: i32) -> i32 {
167    a.wrapping_mul(b)
168}
169
170#[inline]
171pub extern "C" fn jit_div_i32(a: i32, b: i32) -> i32 {
172    if b == 0 {
173        0
174    } else {
175        a.wrapping_div(b)
176    }
177}
178
179#[inline]
180pub extern "C" fn jit_mod_i32(a: i32, b: i32) -> i32 {
181    if b == 0 {
182        0
183    } else {
184        a.wrapping_rem(b)
185    }
186}
187
188#[inline]
189pub extern "C" fn jit_neg_i32(a: i32) -> i32 {
190    a.wrapping_neg()
191}
192
193// ============================================================================
194// i32 Comparisons
195// ============================================================================
196
197#[inline]
198pub extern "C" fn jit_cmp_lt_i32(a: i32, b: i32) -> u8 {
199    (a < b) as u8
200}
201
202#[inline]
203pub extern "C" fn jit_cmp_le_i32(a: i32, b: i32) -> u8 {
204    (a <= b) as u8
205}
206
207#[inline]
208pub extern "C" fn jit_cmp_gt_i32(a: i32, b: i32) -> u8 {
209    (a > b) as u8
210}
211
212#[inline]
213pub extern "C" fn jit_cmp_ge_i32(a: i32, b: i32) -> u8 {
214    (a >= b) as u8
215}
216
217#[inline]
218pub extern "C" fn jit_cmp_eq_i32(a: i32, b: i32) -> u8 {
219    (a == b) as u8
220}
221
222#[inline]
223pub extern "C" fn jit_cmp_ne_i32(a: i32, b: i32) -> u8 {
224    (a != b) as u8
225}
226
227// ============================================================================
228// f64 Math Functions
229// ============================================================================
230
231#[inline]
232pub extern "C" fn jit_sqrt_f64(a: f64) -> f64 {
233    a.sqrt()
234}
235
236#[inline]
237pub extern "C" fn jit_abs_f64(a: f64) -> f64 {
238    a.abs()
239}
240
241#[inline]
242pub extern "C" fn jit_floor_f64(a: f64) -> f64 {
243    a.floor()
244}
245
246#[inline]
247pub extern "C" fn jit_ceil_f64(a: f64) -> f64 {
248    a.ceil()
249}
250
251#[inline]
252pub extern "C" fn jit_round_f64(a: f64) -> f64 {
253    a.round()
254}
255
256#[inline]
257pub extern "C" fn jit_sin_f64(a: f64) -> f64 {
258    a.sin()
259}
260
261#[inline]
262pub extern "C" fn jit_cos_f64(a: f64) -> f64 {
263    a.cos()
264}
265
266#[inline]
267pub extern "C" fn jit_tan_f64(a: f64) -> f64 {
268    a.tan()
269}
270
271#[inline]
272pub extern "C" fn jit_asin_f64(a: f64) -> f64 {
273    a.asin()
274}
275
276#[inline]
277pub extern "C" fn jit_acos_f64(a: f64) -> f64 {
278    a.acos()
279}
280
281#[inline]
282pub extern "C" fn jit_atan_f64(a: f64) -> f64 {
283    a.atan()
284}
285
286#[inline]
287pub extern "C" fn jit_exp_f64(a: f64) -> f64 {
288    a.exp()
289}
290
291#[inline]
292pub extern "C" fn jit_ln_f64(a: f64) -> f64 {
293    a.ln()
294}
295
296#[inline]
297pub extern "C" fn jit_log_f64(a: f64, base: f64) -> f64 {
298    a.log(base)
299}
300
301#[inline]
302pub extern "C" fn jit_pow_f64(a: f64, b: f64) -> f64 {
303    a.powf(b)
304}
305
306// ============================================================================
307// i64 Math Functions
308// ============================================================================
309
310#[inline]
311pub extern "C" fn jit_abs_i64(a: i64) -> i64 {
312    a.wrapping_abs()
313}
314
315// W11-fup-A (Phase 3d, 2026-05-18): Pow on proven Int64 operands. Mirrors
316// the bytecode VM's `PowInt` opcode at `crates/shape-vm/src/executor/
317// arithmetic/mod.rs:146-162` for the non-overflow case: `base.pow(exp as u32)`
318// when `exp >= 0 && exp < u32::MAX`; clamps wrapping for native semantics
319// when `exp` is out of range (signals divergence from the VM's f64 promotion).
320//
321// The VM additionally promotes overflowing i64 results to f64 (line 156);
322// the JIT path does NOT replicate this kind-flip — the result slot's
323// `NativeKind` is stamped at MIR-inference time as `Int64` (same-kind
324// operand inheritance) and §2.7.5 stamp-at-compile-time discipline forbids
325// runtime kind changes. JIT/VM divergence on i64 Pow overflow is a
326// documented residual of the W11-fup-A close (separate follow-up
327// `jit-pow-int-overflow-promotion`).
328#[inline]
329pub extern "C" fn jit_pow_i64(base: i64, exp: i64) -> i64 {
330    if exp < 0 || exp > u32::MAX as i64 {
331        // Out-of-range exponent: VM promotes to f64 via powf; the JIT path
332        // can't kind-flip the result slot at runtime per §2.7.5. Return 0
333        // as a defined-but-divergent value — the divergence is documented
334        // and surfaceable via the kind-mismatch SURFACE in compile_binop
335        // for cases the kind tracker doesn't catch.
336        return 0;
337    }
338    base.wrapping_pow(exp as u32)
339}
340
341// ============================================================================
342// Type Conversions
343// ============================================================================
344
345#[inline]
346pub extern "C" fn jit_i64_to_f64(a: i64) -> f64 {
347    a as f64
348}
349
350#[inline]
351pub extern "C" fn jit_f64_to_i64(a: f64) -> i64 {
352    a as i64
353}
354
355#[inline]
356pub extern "C" fn jit_i32_to_f64(a: i32) -> f64 {
357    a as f64
358}
359
360#[inline]
361pub extern "C" fn jit_f64_to_i32(a: f64) -> i32 {
362    a as i32
363}
364
365#[inline]
366pub extern "C" fn jit_i32_to_i64(a: i32) -> i64 {
367    a as i64
368}
369
370#[inline]
371pub extern "C" fn jit_i64_to_i32(a: i64) -> i32 {
372    a as i32
373}
374
375// ============================================================================
376// Tests
377// ============================================================================
378
379#[cfg(test)]
380mod tests {
381    use super::*;
382
383    // --- f64 arithmetic ---
384
385    #[test]
386    fn test_v2_math_add_f64() {
387        assert_eq!(jit_add_f64(10.0, 32.0), 42.0);
388        assert_eq!(jit_add_f64(-1.5, 2.5), 1.0);
389        assert_eq!(jit_add_f64(0.0, 0.0), 0.0);
390    }
391
392    #[test]
393    fn test_v2_math_sub_f64() {
394        assert_eq!(jit_sub_f64(100.0, 58.0), 42.0);
395        assert_eq!(jit_sub_f64(0.0, 1.0), -1.0);
396    }
397
398    #[test]
399    fn test_v2_math_mul_f64() {
400        assert_eq!(jit_mul_f64(6.0, 7.0), 42.0);
401        assert_eq!(jit_mul_f64(-3.0, 2.0), -6.0);
402        assert_eq!(jit_mul_f64(0.0, 999.0), 0.0);
403    }
404
405    #[test]
406    fn test_v2_math_div_f64() {
407        assert_eq!(jit_div_f64(84.0, 2.0), 42.0);
408        assert!(jit_div_f64(1.0, 0.0).is_infinite());
409        assert!(jit_div_f64(0.0, 0.0).is_nan());
410    }
411
412    #[test]
413    fn test_v2_math_mod_f64() {
414        assert_eq!(jit_mod_f64(10.0, 3.0), 1.0);
415        assert_eq!(jit_mod_f64(10.0, 5.0), 0.0);
416    }
417
418    #[test]
419    fn test_v2_math_neg_f64() {
420        assert_eq!(jit_neg_f64(42.0), -42.0);
421        assert_eq!(jit_neg_f64(-1.0), 1.0);
422        assert_eq!(jit_neg_f64(0.0), 0.0);
423    }
424
425    // --- f64 comparisons ---
426
427    #[test]
428    fn test_v2_math_cmp_f64() {
429        assert_eq!(jit_cmp_lt_f64(1.0, 2.0), 1);
430        assert_eq!(jit_cmp_lt_f64(2.0, 1.0), 0);
431        assert_eq!(jit_cmp_lt_f64(1.0, 1.0), 0);
432
433        assert_eq!(jit_cmp_le_f64(1.0, 2.0), 1);
434        assert_eq!(jit_cmp_le_f64(1.0, 1.0), 1);
435        assert_eq!(jit_cmp_le_f64(2.0, 1.0), 0);
436
437        assert_eq!(jit_cmp_gt_f64(2.0, 1.0), 1);
438        assert_eq!(jit_cmp_gt_f64(1.0, 2.0), 0);
439        assert_eq!(jit_cmp_gt_f64(1.0, 1.0), 0);
440
441        assert_eq!(jit_cmp_ge_f64(2.0, 1.0), 1);
442        assert_eq!(jit_cmp_ge_f64(1.0, 1.0), 1);
443        assert_eq!(jit_cmp_ge_f64(1.0, 2.0), 0);
444
445        assert_eq!(jit_cmp_eq_f64(1.0, 1.0), 1);
446        assert_eq!(jit_cmp_eq_f64(1.0, 2.0), 0);
447
448        assert_eq!(jit_cmp_ne_f64(1.0, 2.0), 1);
449        assert_eq!(jit_cmp_ne_f64(1.0, 1.0), 0);
450    }
451
452    #[test]
453    fn test_v2_math_cmp_f64_nan() {
454        // NaN comparisons: all should return false (0) except ne
455        assert_eq!(jit_cmp_lt_f64(f64::NAN, 1.0), 0);
456        assert_eq!(jit_cmp_le_f64(f64::NAN, 1.0), 0);
457        assert_eq!(jit_cmp_gt_f64(f64::NAN, 1.0), 0);
458        assert_eq!(jit_cmp_ge_f64(f64::NAN, 1.0), 0);
459        assert_eq!(jit_cmp_eq_f64(f64::NAN, f64::NAN), 0);
460        assert_eq!(jit_cmp_ne_f64(f64::NAN, f64::NAN), 1);
461    }
462
463    // --- i64 arithmetic ---
464
465    #[test]
466    fn test_v2_math_add_i64() {
467        assert_eq!(jit_add_i64(10, 32), 42);
468        assert_eq!(jit_add_i64(-1, 1), 0);
469        // Wrapping overflow
470        assert_eq!(jit_add_i64(i64::MAX, 1), i64::MIN);
471    }
472
473    #[test]
474    fn test_v2_math_sub_i64() {
475        assert_eq!(jit_sub_i64(100, 58), 42);
476        assert_eq!(jit_sub_i64(0, 1), -1);
477        // Wrapping underflow
478        assert_eq!(jit_sub_i64(i64::MIN, 1), i64::MAX);
479    }
480
481    #[test]
482    fn test_v2_math_mul_i64() {
483        assert_eq!(jit_mul_i64(6, 7), 42);
484        assert_eq!(jit_mul_i64(-3, 2), -6);
485        assert_eq!(jit_mul_i64(0, i64::MAX), 0);
486    }
487
488    #[test]
489    fn test_v2_math_div_i64() {
490        assert_eq!(jit_div_i64(84, 2), 42);
491        assert_eq!(jit_div_i64(7, 2), 3); // truncation
492        assert_eq!(jit_div_i64(1, 0), 0); // div by zero => 0
493        // MIN / -1 would overflow; wrapping_div handles it
494        assert_eq!(jit_div_i64(i64::MIN, -1), i64::MIN);
495    }
496
497    #[test]
498    fn test_v2_math_mod_i64() {
499        assert_eq!(jit_mod_i64(10, 3), 1);
500        assert_eq!(jit_mod_i64(10, 5), 0);
501        assert_eq!(jit_mod_i64(1, 0), 0); // mod by zero => 0
502    }
503
504    #[test]
505    fn test_v2_math_neg_i64() {
506        assert_eq!(jit_neg_i64(42), -42);
507        assert_eq!(jit_neg_i64(-1), 1);
508        assert_eq!(jit_neg_i64(0), 0);
509        // Wrapping: -MIN overflows
510        assert_eq!(jit_neg_i64(i64::MIN), i64::MIN);
511    }
512
513    // --- i64 comparisons ---
514
515    #[test]
516    fn test_v2_math_cmp_i64() {
517        assert_eq!(jit_cmp_lt_i64(1, 2), 1);
518        assert_eq!(jit_cmp_lt_i64(2, 1), 0);
519        assert_eq!(jit_cmp_le_i64(1, 1), 1);
520        assert_eq!(jit_cmp_gt_i64(2, 1), 1);
521        assert_eq!(jit_cmp_ge_i64(1, 1), 1);
522        assert_eq!(jit_cmp_eq_i64(42, 42), 1);
523        assert_eq!(jit_cmp_eq_i64(1, 2), 0);
524        assert_eq!(jit_cmp_ne_i64(1, 2), 1);
525        assert_eq!(jit_cmp_ne_i64(1, 1), 0);
526    }
527
528    // --- i32 arithmetic ---
529
530    #[test]
531    fn test_v2_math_add_i32() {
532        assert_eq!(jit_add_i32(10, 32), 42);
533        assert_eq!(jit_add_i32(i32::MAX, 1), i32::MIN);
534    }
535
536    #[test]
537    fn test_v2_math_sub_i32() {
538        assert_eq!(jit_sub_i32(100, 58), 42);
539        assert_eq!(jit_sub_i32(i32::MIN, 1), i32::MAX);
540    }
541
542    #[test]
543    fn test_v2_math_mul_i32() {
544        assert_eq!(jit_mul_i32(6, 7), 42);
545        assert_eq!(jit_mul_i32(0, i32::MAX), 0);
546    }
547
548    #[test]
549    fn test_v2_math_div_i32() {
550        assert_eq!(jit_div_i32(84, 2), 42);
551        assert_eq!(jit_div_i32(1, 0), 0);
552        assert_eq!(jit_div_i32(i32::MIN, -1), i32::MIN);
553    }
554
555    #[test]
556    fn test_v2_math_mod_i32() {
557        assert_eq!(jit_mod_i32(10, 3), 1);
558        assert_eq!(jit_mod_i32(1, 0), 0);
559    }
560
561    #[test]
562    fn test_v2_math_neg_i32() {
563        assert_eq!(jit_neg_i32(42), -42);
564        assert_eq!(jit_neg_i32(i32::MIN), i32::MIN);
565    }
566
567    // --- i32 comparisons ---
568
569    #[test]
570    fn test_v2_math_cmp_i32() {
571        assert_eq!(jit_cmp_lt_i32(1, 2), 1);
572        assert_eq!(jit_cmp_lt_i32(2, 1), 0);
573        assert_eq!(jit_cmp_le_i32(1, 1), 1);
574        assert_eq!(jit_cmp_gt_i32(2, 1), 1);
575        assert_eq!(jit_cmp_ge_i32(1, 1), 1);
576        assert_eq!(jit_cmp_eq_i32(42, 42), 1);
577        assert_eq!(jit_cmp_ne_i32(1, 2), 1);
578        assert_eq!(jit_cmp_ne_i32(1, 1), 0);
579    }
580
581    // --- f64 math functions ---
582
583    #[test]
584    fn test_v2_math_sqrt_f64() {
585        assert_eq!(jit_sqrt_f64(4.0), 2.0);
586        assert_eq!(jit_sqrt_f64(0.0), 0.0);
587        assert!(jit_sqrt_f64(-1.0).is_nan());
588    }
589
590    #[test]
591    fn test_v2_math_abs_f64() {
592        assert_eq!(jit_abs_f64(-42.0), 42.0);
593        assert_eq!(jit_abs_f64(42.0), 42.0);
594        assert_eq!(jit_abs_f64(0.0), 0.0);
595    }
596
597    #[test]
598    fn test_v2_math_floor_ceil_round_f64() {
599        assert_eq!(jit_floor_f64(2.7), 2.0);
600        assert_eq!(jit_floor_f64(-2.3), -3.0);
601        assert_eq!(jit_ceil_f64(2.3), 3.0);
602        assert_eq!(jit_ceil_f64(-2.7), -2.0);
603        assert_eq!(jit_round_f64(2.5), 3.0);
604        assert_eq!(jit_round_f64(2.4), 2.0);
605    }
606
607    #[test]
608    fn test_v2_math_trig_f64() {
609        let pi = std::f64::consts::PI;
610        assert!((jit_sin_f64(0.0)).abs() < 1e-15);
611        assert!((jit_cos_f64(0.0) - 1.0).abs() < 1e-15);
612        assert!((jit_sin_f64(pi / 2.0) - 1.0).abs() < 1e-15);
613        assert!((jit_tan_f64(0.0)).abs() < 1e-15);
614        assert!((jit_asin_f64(1.0) - pi / 2.0).abs() < 1e-15);
615        assert!((jit_acos_f64(1.0)).abs() < 1e-15);
616        assert!((jit_atan_f64(0.0)).abs() < 1e-15);
617    }
618
619    #[test]
620    fn test_v2_math_exp_ln_f64() {
621        assert!((jit_exp_f64(0.0) - 1.0).abs() < 1e-15);
622        assert!((jit_ln_f64(1.0)).abs() < 1e-15);
623        assert!((jit_exp_f64(1.0) - std::f64::consts::E).abs() < 1e-14);
624        assert!((jit_ln_f64(std::f64::consts::E) - 1.0).abs() < 1e-15);
625    }
626
627    #[test]
628    fn test_v2_math_log_f64() {
629        assert!((jit_log_f64(8.0, 2.0) - 3.0).abs() < 1e-14);
630        assert!((jit_log_f64(100.0, 10.0) - 2.0).abs() < 1e-14);
631    }
632
633    #[test]
634    fn test_v2_math_pow_f64() {
635        assert_eq!(jit_pow_f64(2.0, 10.0), 1024.0);
636        assert_eq!(jit_pow_f64(3.0, 0.0), 1.0);
637        assert_eq!(jit_pow_f64(0.0, 5.0), 0.0);
638        assert!((jit_pow_f64(4.0, 0.5) - 2.0).abs() < 1e-15);
639    }
640
641    // --- i64 math functions ---
642
643    #[test]
644    fn test_v2_math_abs_i64() {
645        assert_eq!(jit_abs_i64(-42), 42);
646        assert_eq!(jit_abs_i64(42), 42);
647        assert_eq!(jit_abs_i64(0), 0);
648        // Wrapping: abs(MIN) overflows
649        assert_eq!(jit_abs_i64(i64::MIN), i64::MIN);
650    }
651
652    // --- type conversions ---
653
654    #[test]
655    fn test_v2_math_i64_to_f64() {
656        assert_eq!(jit_i64_to_f64(42), 42.0);
657        assert_eq!(jit_i64_to_f64(-1), -1.0);
658        assert_eq!(jit_i64_to_f64(0), 0.0);
659    }
660
661    #[test]
662    fn test_v2_math_f64_to_i64() {
663        assert_eq!(jit_f64_to_i64(42.9), 42);
664        assert_eq!(jit_f64_to_i64(-1.1), -1);
665        assert_eq!(jit_f64_to_i64(0.0), 0);
666    }
667
668    #[test]
669    fn test_v2_math_i32_to_f64() {
670        assert_eq!(jit_i32_to_f64(42), 42.0);
671        assert_eq!(jit_i32_to_f64(-1), -1.0);
672    }
673
674    #[test]
675    fn test_v2_math_f64_to_i32() {
676        assert_eq!(jit_f64_to_i32(42.9), 42);
677        assert_eq!(jit_f64_to_i32(-1.1), -1);
678    }
679
680    #[test]
681    fn test_v2_math_i32_i64_conversions() {
682        assert_eq!(jit_i32_to_i64(42), 42i64);
683        assert_eq!(jit_i32_to_i64(-1), -1i64);
684        assert_eq!(jit_i64_to_i32(42), 42i32);
685        // Truncation
686        assert_eq!(jit_i64_to_i32(i64::MAX), -1i32);
687    }
688}