66/// 
77/// Based on https://github.com/NetBSD/src/blob/trunk/lib/libm/arch/i387/s_ceil.S 
88/// (written by J.T. Conklin <[email protected] >). 9- # [ unsafe ( naked ) ] 
10- pub   extern   "C"   fn   ceil ( _ :   f64 )  ->  f64   { 
11-     core :: arch :: naked_asm! ( 
12-          "pushl  %ebp" , 
13-         "movl   %esp,%ebp" , 
14-         "subl    $8,%esp" , 
15-         // Store fpu control word .
16-         "fstcw    -4(%ebp)" , 
17-         "movw     -4(%ebp), %dx", 
18-         // Round towards +oo.  
19-         "orw $0x0800,%dx" , 
20-         "andw     $0xfbff,%dx" , 
21-         "movw     %dx,-8(%ebp)" , 
22-         // Load modified control word 
23-         "fldcw    -8(%ebp )", 
24-         // Round. 
25-         "fldl     8(%ebp)" , 
26-         "frndint" , 
27-         // Restore original control word.  
28-         "fldcw   -4(%ebp)" , 
29-         // Restore esp and ebp and return 
30-         "leave" , 
31-         "ret" , 
32-         options ( att_syntax ) 
33-     ) 
9+ pub   fn   ceil ( mut   x :   f64 )  ->  f64   { 
10+      // We save and later restore the FPU control word. 
11+     let   mut  cw_orig :   u16  =  0 ; 
12+     unsafe   { 
13+         core :: arch :: asm! ( 
14+              "fstcw    ({cw_ptr})" ,        // Save the cw 
15+              "movw    ({cw_ptr}), %dx" ,   // .. .
16+              "orw      $0x0800, %dx" ,      // Set rounding control to 0b10 (+∞) ,
17+              "andw     $0xfbff,  %dx",      // preserving other controls 
18+              "movw    %dx, ({cw_ptr})" ,   // Apply cw  
19+              "fldcw    ({cw_ptr})" ,       // ... 
20+              "fldl      ({x_ptr})" ,        // Push x to the stack 
21+             "frndint" ,                   // Round 
22+              "fldcw    ({cw_ptr})" ,       // Restore cw 
23+              "fstpl    ({x_ptr} )",         // Save rounded x to mem 
24+             cw_ptr = in ( reg )   & mut  cw_orig , 
25+             x_ptr = in ( reg )   & mut  x , 
26+             out ( "dx" )  _ ,                 // Cw scratch 
27+              // All the x87 FPU stack is used, all registers must be clobbered  
28+             out ( "st(0)" )  _ ,  out ( "st(1)" )  _ ,  out ( "st(2)" )  _ ,  out ( "st(3)" )  _ , 
29+             out ( "st(4)" )  _ ,  out ( "st(5)" )  _ ,  out ( "st(6)" )  _ ,  out ( "st(7)" )  _ , 
30+             options ( att_syntax ) 
31+         ) 
32+     } 
33+     x 
3434} 
3535
3636/// Use an alternative implementation on x86, because the 
@@ -39,29 +39,29 @@ pub extern "C" fn ceil(_: f64) -> f64 {
3939/// 
4040/// Based on https://github.com/NetBSD/src/blob/trunk/lib/libm/arch/i387/s_floor.S 
4141/// (written by J.T. Conklin <[email protected] >). 42- # [ unsafe ( naked ) ] 
43- pub   extern   "C"   fn   floor ( _ :   f64 )  ->  f64   { 
44-     core :: arch :: naked_asm! ( 
45-          "pushl  %ebp" , 
46-         "movl   %esp,%ebp" , 
47-         "subl    $8,%esp" , 
48-         // Store fpu control word .
49-         "fstcw    -4(%ebp)" , 
50-         "movw     -4(%ebp), %dx", 
51-         // Round towards -oo.  
52-         "orw	$0x0400,%dx" , 
53-         "andw	$0xf7ff,%dx" , 
54-         "movw    %dx,-8(%ebp)" , 
55-         // Load modified control word 
56-         "fldcw    -8(%ebp )", 
57-         // Round. 
58-         "fldl     8(%ebp)" , 
59-         "frndint" , 
60-         // Restore original control word.  
61-         "fldcw   -4(%ebp)" , 
62-         // Restore esp and ebp and return 
63-         "leave" , 
64-         "ret" , 
65-         options ( att_syntax ) 
66-     ) 
42+ pub   fn   floor ( mut   x :   f64 )  ->  f64   { 
43+      // We save and later restore the FPU control word. 
44+     let   mut  cw_orig :   u16  =  0 ; 
45+     unsafe   { 
46+         core :: arch :: asm! ( 
47+              "fstcw    ({cw_ptr})" ,        // Save the cw 
48+              "movw    ({cw_ptr}), %dx" ,   // .. .
49+              "orw      $0x0400, %dx" ,      // Set rounding control to 0b01 (-∞) ,
50+              "andw     $0xf7ff,  %dx",      // preserving other controls 
51+              "movw    %dx, ({cw_ptr})" ,   // Apply cw  
52+              "fldcw    ({cw_ptr})" ,       // ... 
53+              "fldl     ({x_ptr})" ,        // Push x to the stack 
54+              "frndint" ,                   // Round 
55+              "fldcw    ({cw_ptr})" ,       // Restore cw 
56+              "fstpl    ({x_ptr} )",         // Save rounded x to mem 
57+             cw_ptr = in ( reg )   & mut  cw_orig , 
58+             x_ptr = in ( reg )   & mut  x , 
59+             out ( "dx" )  _ ,                 // Cw scratch 
60+              // All the x87 FPU stack is used, all registers must be clobbered  
61+             out ( "st(0)" )  _ ,  out ( "st(1)" )  _ ,  out ( "st(2)" )  _ ,  out ( "st(3)" )  _ , 
62+             out ( "st(4)" )  _ ,  out ( "st(5)" )  _ ,  out ( "st(6)" )  _ ,  out ( "st(7)" )  _ , 
63+             options ( att_syntax ) 
64+         ) 
65+     } 
66+     x 
6767} 
0 commit comments