You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/inline-assembly.md
+171-1Lines changed: 171 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -563,8 +563,16 @@ The availability of supported types for a particular register class may depend o
563
563
564
564
> **Note**: For the purposes of the above table pointers, function pointers and `isize`/`usize` are treated as the equivalent integer type (`i16`/`i32`/`i64` depending on the target).
let z = unsafe{core::arch::x86_64::_mm_set_epi64x(1,0)};
570
578
// We can't pass an `__m128i` to a `reg` input
@@ -689,6 +697,14 @@ Here is the list of all supported register aliases:
689
697
| LoongArch |`$f[8-23]`|`$ft[0-15]`|
690
698
| LoongArch |`$f[24-31]`|`$fs[0-7]`|
691
699
700
+
```rust
701
+
# #[cfg(target_arch ="x86_64")] {
702
+
letz=0i64;
703
+
// rax is an alias for eax and ax
704
+
unsafe { core::arch::asm!("", in("rax") z); }
705
+
# }
706
+
```
707
+
692
708
r[asm.register-names.not-for-io]
693
709
Some registers cannot be used for input or output operands:
694
710
@@ -714,6 +730,14 @@ Some registers cannot be used for input or output operands:
714
730
| s390x |`c[0-15]`| Reserved by the kernel. |
715
731
| s390x |`a[0-1]`| Reserved for system use. |
716
732
733
+
```rust,compile_fail
734
+
# #[cfg(target_arch = "x86_64")] {
735
+
// bp is reserved
736
+
unsafe { core::arch::asm!("", in("bp") 5i32); }
737
+
# }
738
+
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
739
+
```
740
+
717
741
r[asm.register-names.fp-bp-reserved]
718
742
The frame pointer and base pointer registers are reserved for internal use by LLVM. While `asm!` statements cannot explicitly specify the use of reserved registers, in some cases LLVM will allocate one of these reserved registers for `reg` operands. Assembly code making use of reserved registers should be careful since `reg` operands may use the same registers.
719
743
@@ -727,6 +751,15 @@ These modifiers do not affect register allocation, but change the way operands a
727
751
r[asm.template-modifiers.only-one]
728
752
Only one modifier is allowed per template placeholder.
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
760
+
```
761
+
762
+
730
763
r[asm.template-modifiers.supported-modifiers]
731
764
The supported modifiers are a subset of LLVM's (and GCC's) [asm template argument modifiers][llvm-argmod], but do not use the same letter codes.
732
765
@@ -792,12 +825,41 @@ r[asm.abi-clobbers.intro]
792
825
The `clobber_abi` keyword can be used to apply a default set of clobbers to an `asm!` block.
793
826
This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then `lateout("...") _` is implicitly added to the operands list (where the `...` is replaced by the register's name).
`clobber_abi` may be specified any number of times. It will insert a clobber for all unique registers in the union of all specified calling conventions.
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
861
+
```
862
+
801
863
r[asm.abi-clobbers.explicit-have-precedence]
802
864
Explicit register outputs have precedence over the implicit clobbers inserted by `clobber_abi`: a clobber will only be inserted for a register if that register is not used as an output.
This allows the compiler to execute the `asm!` block fewer times than specified in the program (e.g. by hoisting it out of a loop) or even eliminate it entirely if the outputs are not used.
835
897
The `pure` option must be combined with either the `nomem` or `readonly` options, otherwise a compile-time error is emitted.
unsafe { core::arch::asm!("inc {}", inout(reg) x => z, options(pure)); }
912
+
assert_eq!(z, 0);
913
+
# }
914
+
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
915
+
```
916
+
837
917
r[asm.options.supported-options.nomem]
838
918
-`nomem`: The `asm!` block does not read from or write to any memory accessible outside of the `asm!` block.
839
919
This allows the compiler to cache the values of modified global variables in registers across the `asm!` block since it knows that they are not read or written to by the `asm!`.
840
920
The compiler also assumes that this `asm!` block does not perform any kind of synchronization with other threads, e.g. via fences.
841
921
922
+
<!-- no_run: This test has unpredictable or undefined behaviour at runtime -->
-`readonly`: The `asm!` block does not write to any memory accessible outside of the `asm!` block.
844
934
This allows the compiler to cache the values of unmodified global variables in registers across the `asm!` block since it knows that they are not written to by the `asm!`.
845
935
The compiler also assumes that this `asm!` block does not perform any kind of synchronization with other threads, e.g. via fences.
846
936
937
+
<!-- no_run: This test has undefined behaviour at runtime -->
0 commit comments