Skip to content

Commit 5067ad2

Browse files
committed
Finish adding inline tests to inline-assembly.md
1 parent be920cf commit 5067ad2

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/inline-assembly.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,39 @@ r[asm.rules.x86-x87]
11091109
- On x86, the x87 floating-point register stack must remain unchanged unless all of the `st([0-7])` registers have been marked as clobbered with `out("st(0)") _, out("st(1)") _, ...`.
11101110
- If all x87 registers are clobbered then the x87 register stack is guaranteed to be empty upon entering an `asm` block. Assembly code must ensure that the x87 register stack is also empty when exiting the asm block.
11111111

1112+
```rust
1113+
# #[cfg(target_arch = "x86_64")]
1114+
pub fn fadd(x: f64, y: f64) -> f64{
1115+
let mut out = 0f64;
1116+
let mut top = 0u16;
1117+
// we can do complex stuff with x87 if we clobber the entire x87 stack
1118+
unsafe{ core::arch::asm!(
1119+
"fld qword ptr [{x}]",
1120+
"fld qword ptr [{y}])",
1121+
"faddp",
1122+
"fstp qword ptr [{out}]",
1123+
"xor eax, eax",
1124+
"fstsw ax",
1125+
"shl eax, 11",
1126+
x = in(reg) &x,
1127+
y = in(reg) &y,
1128+
out = in(reg) &mut out,
1129+
out("st(0)") _, out("st(1)") _, out("st(2)") _, out("st(3)") _,
1130+
out("st(4)") _, out("st(5)") _, out("st(6)") _, out("st(7)") _,
1131+
out("eax") top
1132+
);}
1133+
1134+
assert_eq!(top & 0x7, 0);
1135+
out
1136+
}
1137+
1138+
pub fn main(){
1139+
# #[cfg(target_arch = "x86_64")]{
1140+
assert_eq!(fadd(1.0, 1.0), 2.0);
1141+
# }
1142+
}
1143+
```
1144+
11121145
r[asm.rules.only-on-exit]
11131146
- The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting an `asm!` block.
11141147
- This means that `asm!` blocks that never return (even if not marked `noreturn`) don't need to preserve these registers.
@@ -1223,7 +1256,18 @@ The following directives are guaranteed to be supported by the assembler:
12231256
- `.uleb128`
12241257
- `.word`
12251258

1259+
```rust
1260+
# #[cfg(target_arch = "x86_64")] {
1261+
let bytes: *const u8;
1262+
let len: usize;
1263+
// `push` and `pop` are UB when used with nostack
1264+
unsafe { core::arch::asm!("jmp 3f", "2: .ascii \"Hello World!\"", "3: lea {bytes}, [2b+rip]", "mov {len}, 12", bytes = out(reg) bytes, len = out(reg) len); }
12261265

1266+
let s = unsafe{core::str::from_utf8_unchecked(core::slice::from_raw_parts(bytes, len))};
1267+
1268+
assert_eq!(s, "Hello World!");
1269+
# }
1270+
```
12271271

12281272
#### Target Specific Directive Support
12291273

0 commit comments

Comments
 (0)