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 ( x : f64 ) -> f64 {
10+ unsafe { ceil_helper ( x) }
3411}
3512
3613/// Use an alternative implementation on x86, because the
@@ -39,29 +16,73 @@ pub extern "C" fn ceil(_: f64) -> f64 {
3916///
4017/// Based on https://github.com/NetBSD/src/blob/trunk/lib/libm/arch/i387/s_floor.S
4118/// (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) }
6721}
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