Skip to content

Commit 1680fd8

Browse files
committed
implement floor and ceil with global assembly on i586
1 parent ffe715a commit 1680fd8

File tree

1 file changed

+71
-50
lines changed

1 file changed

+71
-50
lines changed

libm/src/math/arch/i586.rs

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,8 @@
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

Comments
 (0)