about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/unstable-book/src/SUMMARY.md1
-rw-r--r--src/doc/unstable-book/src/asm.md2
-rw-r--r--src/doc/unstable-book/src/global_asm.md78
3 files changed, 81 insertions, 0 deletions
diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md
index 54e602a81db..8221d22eaac 100644
--- a/src/doc/unstable-book/src/SUMMARY.md
+++ b/src/doc/unstable-book/src/SUMMARY.md
@@ -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)
diff --git a/src/doc/unstable-book/src/asm.md b/src/doc/unstable-book/src/asm.md
index 032d9d81240..5e68be633e7 100644
--- a/src/doc/unstable-book/src/asm.md
+++ b/src/doc/unstable-book/src/asm.md
@@ -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).
diff --git a/src/doc/unstable-book/src/global_asm.md b/src/doc/unstable-book/src/global_asm.md
new file mode 100644
index 00000000000..f092a4ad664
--- /dev/null
+++ b/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.