6
6
///
7
7
/// Based on https://github.com/NetBSD/src/blob/trunk/lib/libm/arch/i387/s_ceil.S
8
8
/// (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 ( x : f64 ) -> f64 {
10
+ unsafe { ceil_helper ( x) }
34
11
}
35
12
36
13
/// Use an alternative implementation on x86, because the
@@ -39,29 +16,73 @@ pub extern "C" fn ceil(_: f64) -> f64 {
39
16
///
40
17
/// Based on https://github.com/NetBSD/src/blob/trunk/lib/libm/arch/i387/s_floor.S
41
18
/// (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
- )
19
+ pub fn floor ( x : f64 ) -> f64 {
20
+ unsafe { floor_helper ( x) }
67
21
}
22
+
23
+ extern "cdecl" {
24
+ fn ceil_helper ( _: f64 ) -> f64 ;
25
+ fn floor_helper ( _: f64 ) -> f64 ;
26
+ }
27
+
28
+ core:: arch:: global_asm!(
29
+ ".pushsection .text.{ceil},\" ax\" ,@progbits" ,
30
+ ".p2align 2" ,
31
+ ".global {ceil}" ,
32
+ ".type {ceil}, @function" ,
33
+ "{ceil}:" ,
34
+ "pushl %ebp" ,
35
+ "movl %esp,%ebp" ,
36
+ "subl $8,%esp" ,
37
+ // Store fpu control word.
38
+ "fstcw -4(%ebp)" ,
39
+ "movw -4(%ebp),%dx" ,
40
+ // Round towards +oo.
41
+ "orw $0x0800,%dx" ,
42
+ "andw $0xfbff,%dx" ,
43
+ "movw %dx,-8(%ebp)" ,
44
+ // Load modified control word
45
+ "fldcw -8(%ebp)" ,
46
+ // Round.
47
+ "fldl 8(%ebp)" ,
48
+ "frndint" ,
49
+ // Restore original control word.
50
+ "fldcw -4(%ebp)" ,
51
+ // Restore esp and ebp and return
52
+ "leave" ,
53
+ "ret" ,
54
+ ".size {ceil}, . - {ceil}" ,
55
+ options( att_syntax) ,
56
+ ceil = sym ceil_helper,
57
+ ) ;
58
+
59
+ core:: arch:: global_asm!(
60
+ ".pushsection .text.{floor},\" ax\" ,@progbits" ,
61
+ ".p2align 2" ,
62
+ ".global {floor}" ,
63
+ ".type {floor}, @function" ,
64
+ "{floor}:" ,
65
+ "pushl %ebp" ,
66
+ "movl %esp,%ebp" ,
67
+ "subl $8,%esp" ,
68
+ // Store fpu control word.
69
+ "fstcw -4(%ebp)" ,
70
+ "movw -4(%ebp),%dx" ,
71
+ // Round towards -oo.
72
+ "orw $0x0400,%dx" ,
73
+ "andw $0xf7ff,%dx" ,
74
+ "movw %dx,-8(%ebp)" ,
75
+ // Load modified control word
76
+ "fldcw -8(%ebp)" ,
77
+ // Round.
78
+ "fldl 8(%ebp)" ,
79
+ "frndint" ,
80
+ // Restore original control word.
81
+ "fldcw -4(%ebp)" ,
82
+ // Restore esp and ebp and return
83
+ "leave" ,
84
+ "ret" ,
85
+ ".size {floor}, . - {floor}" ,
86
+ options( att_syntax) ,
87
+ floor = sym floor_helper,
88
+ ) ;
0 commit comments