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
@@ -552,8 +552,16 @@ The availability of supported types for a particular register class may depend o
552
552
553
553
> **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)};
559
567
// We can't pass an `__m128i` to a `reg` input
@@ -673,6 +681,14 @@ Here is the list of all supported register aliases:
673
681
| LoongArch |`$f[8-23]`|`$ft[0-15]`|
674
682
| LoongArch |`$f[24-31]`|`$fs[0-7]`|
675
683
684
+
```rust
685
+
# #[cfg(target_arch ="x86_64")] {
686
+
letz=0i64;
687
+
// rax is an alias for eax and ax
688
+
unsafe { core::arch::asm!("", in("rax") z); }
689
+
# }
690
+
```
691
+
676
692
r[asm.register-names.not-for-io]
677
693
Some registers cannot be used for input or output operands:
678
694
@@ -693,6 +709,14 @@ Some registers cannot be used for input or output operands:
693
709
| LoongArch |`$r2` or `$tp`| This is reserved for TLS. |
694
710
| LoongArch |`$r21`| This is reserved by the ABI. |
695
711
712
+
```rust,compile_fail
713
+
# #[cfg(target_arch = "x86_64")] {
714
+
// bp is reserved
715
+
unsafe { core::arch::asm!("", in("bp") 5i32); }
716
+
# }
717
+
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
718
+
```
719
+
696
720
r[asm.register-names.fp-bp-reserved]
697
721
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.
698
722
@@ -707,6 +731,15 @@ These modifiers do not affect register allocation, but change the way operands a
707
731
r[asm.template-modifiers.only-one]
708
732
Only one modifier is allowed per template placeholder.
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
740
+
```
741
+
742
+
710
743
r[asm.template-modifiers.supported-modifiers]
711
744
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.
712
745
@@ -770,12 +803,41 @@ r[asm.abi-clobbers.intro]
770
803
The `clobber_abi` keyword can be used to apply a default set of clobbers to an `asm!` block.
771
804
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");
839
+
```
840
+
779
841
r[asm.abi-clobbers.explicit-have-precedence]
780
842
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.
811
873
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)); }
888
+
assert_eq!(z, 0);
889
+
# }
890
+
# #[cfg(not(target_arch = "x86_64"))] core::compile_error!("Test not supported on this arch");
891
+
```
892
+
813
893
r[asm.options.supported-options.nomem]
814
894
-`nomem`: The `asm!` block does not read from or write to any memory accessible outside of the `asm!` block.
815
895
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!`.
816
896
The compiler also assumes that this `asm!` block does not perform any kind of synchronization with other threads, e.g. via fences.
817
897
898
+
<!-- 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.
820
910
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!`.
821
911
The compiler also assumes that this `asm!` block does not perform any kind of synchronization with other threads, e.g. via fences.
822
912
913
+
<!-- no_run: This test has undefined behaviour at runtime -->
0 commit comments