Skip to content

Commit

Permalink
Update unstable book with global_asm feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mrhota committed Apr 13, 2017
1 parent 9240054 commit 4b9de4c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/doc/unstable-book/src/SUMMARY.md
Expand Up @@ -83,6 +83,7 @@
- [future_atomic_orderings](future-atomic-orderings.md)
- [generic_param_attrs](generic-param-attrs.md)
- [get_type_id](get-type-id.md)
- [global_asm](global_asm.md)
- [heap_api](heap-api.md)
- [i128](i128.md)
- [i128_type](i128-type.md)
Expand Down
2 changes: 2 additions & 0 deletions src/doc/unstable-book/src/asm.md
Expand Up @@ -189,3 +189,5 @@ constraints, etc.

[llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions

If you need more power and don't mind losing some of the niceties of
`asm!`, check out [global_asm](global_asm.html).
78 changes: 78 additions & 0 deletions src/doc/unstable-book/src/global_asm.md
@@ -0,0 +1,78 @@
# `global_asm`

The tracking issue for this feature is: [#35119]

[#35119]: https://github.com/rust-lang/rust/issues/35119

------------------------

The `global_asm!` macro allows the programmer to write arbitrary
assembly outside the scope of a function body, passing it through
`rustc` and `llvm` to the assembler. The macro is a no-frills
interface to LLVM's concept of [module-level inline assembly]. That is,
all caveats applicable to LLVM's module-level inline assembly apply
to `global_asm!`.

[module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly

`global_asm!` fills a role not currently satisfied by either `asm!`
or `#[naked]` functions. The programmer has _all_ features of the
assembler at their disposal. The linker will expect to resolve any
symbols defined in the inline assembly, modulo any symbols marked as
external. It also means syntax for directives and assembly follow the
conventions of the assembler in your toolchain.

A simple usage looks like this:

```rust,ignore
# #![feature(global_asm)]
# you also need relevant target_arch cfgs
global_asm!(include_str("something_neato.s"));
```

And a more complicated usage looks like this:

```rust,ignore
# #![feature(global_asm)]
# #![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod sally {
global_asm!(r#"
.global foo
foo:
jmp baz
"#);
#[no_mangle]
pub unsafe extern "C" fn baz() {}
}
// the symbols `foo` and `bar` are global, no matter where
// `global_asm!` was used.
extern "C" {
fn foo();
fn bar();
}
pub mod harry {
global_asm!(r#"
.global bar
bar:
jmp quux
"#);
#[no_mangle]
pub unsafe extern "C" fn quux() {}
}
```

You may use `global_asm!` multiple times, anywhere in your crate, in
whatever way suits you. The effect is as if you concatenated all
usages and placed the larger, single usage in the crate root.

------------------------

If you don't need quite as much power and flexibility as
`global_asm!` provides, and you don't mind restricting your inline
assembly to `fn` bodies only, you might try the [asm](asm.html)
feature instead.

0 comments on commit 4b9de4c

Please sign in to comment.