Auto merge of #41156 - TimNN:rollup, r=TimNN
Rollup of 4 pull requests - Successful merges: #41135, #41143, #41146, #41152 - Failed merges:
This commit is contained in:
commit
3178d4318c
@ -472,10 +472,10 @@ class RustBuild(object):
|
||||
cputype = 'i686'
|
||||
elif cputype in {'xscale', 'arm'}:
|
||||
cputype = 'arm'
|
||||
elif cputype in {'armv6l', 'armv7l', 'armv8l'}:
|
||||
elif cputype == 'armv6l':
|
||||
cputype = 'arm'
|
||||
ostype += 'eabihf'
|
||||
elif cputype == 'armv7l':
|
||||
elif cputype in {'armv7l', 'armv8l'}:
|
||||
cputype = 'armv7'
|
||||
ostype += 'eabihf'
|
||||
elif cputype == 'aarch64':
|
||||
|
@ -5,3 +5,38 @@ The tracking issue for this feature is: [#38487]
|
||||
[#38487]: https://github.com/rust-lang/rust/issues/38487
|
||||
|
||||
------------------------
|
||||
|
||||
In the MSP430 architecture, interrupt handlers have a special calling
|
||||
convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply
|
||||
the right calling convention to the interrupt handlers you define.
|
||||
|
||||
<!-- NOTE(ignore) this example is specific to the msp430 target -->
|
||||
|
||||
``` rust,ignore
|
||||
#![feature(abi_msp430_interrupt)]
|
||||
#![no_std]
|
||||
|
||||
// Place the interrupt handler at the appropriate memory address
|
||||
// (Alternatively, you can use `#[used]` and remove `pub` and `#[no_mangle]`)
|
||||
#[link_section = "__interrupt_vector_10"]
|
||||
#[no_mangle]
|
||||
pub static TIM0_VECTOR: extern "msp430-interrupt" fn() = tim0;
|
||||
|
||||
// The interrupt handler
|
||||
extern "msp430-interrupt" fn tim0() {
|
||||
// ..
|
||||
}
|
||||
```
|
||||
|
||||
``` text
|
||||
$ msp430-elf-objdump -CD ./target/msp430/release/app
|
||||
Disassembly of section __interrupt_vector_10:
|
||||
|
||||
0000fff2 <TIM0_VECTOR>:
|
||||
fff2: 00 c0 interrupt service routine at 0xc000
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0000c000 <int::tim0>:
|
||||
c000: 00 13 reti
|
||||
```
|
||||
|
@ -1,5 +1,60 @@
|
||||
# `abi_ptx`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
The tracking issue for this feature is: [#38788]
|
||||
|
||||
[#38788]: https://github.com/rust-lang/rust/issues/38788
|
||||
|
||||
------------------------
|
||||
|
||||
When emitting PTX code, all vanilla Rust functions (`fn`) get translated to
|
||||
"device" functions. These functions are *not* callable from the host via the
|
||||
CUDA API so a crate with only device functions is not too useful!
|
||||
|
||||
OTOH, "global" functions *can* be called by the host; you can think of them
|
||||
as the real public API of your crate. To produce a global function use the
|
||||
`"ptx-kernel"` ABI.
|
||||
|
||||
<!-- NOTE(ignore) this example is specific to the nvptx targets -->
|
||||
|
||||
``` rust,ignore
|
||||
#![feature(abi_ptx)]
|
||||
#![no_std]
|
||||
|
||||
pub unsafe extern "ptx-kernel" fn global_function() {
|
||||
device_function();
|
||||
}
|
||||
|
||||
pub fn device_function() {
|
||||
// ..
|
||||
}
|
||||
```
|
||||
|
||||
``` text
|
||||
$ xargo rustc --target nvptx64-nvidia-cuda --release -- --emit=asm
|
||||
|
||||
$ cat $(find -name '*.s')
|
||||
//
|
||||
// Generated by LLVM NVPTX Back-End
|
||||
//
|
||||
|
||||
.version 3.2
|
||||
.target sm_20
|
||||
.address_size 64
|
||||
|
||||
// .globl _ZN6kernel15global_function17h46111ebe6516b382E
|
||||
|
||||
.visible .entry _ZN6kernel15global_function17h46111ebe6516b382E()
|
||||
{
|
||||
|
||||
|
||||
ret;
|
||||
}
|
||||
|
||||
// .globl _ZN6kernel15device_function17hd6a0e4993bbf3f78E
|
||||
.visible .func _ZN6kernel15device_function17hd6a0e4993bbf3f78E()
|
||||
{
|
||||
|
||||
|
||||
ret;
|
||||
}
|
||||
```
|
||||
|
@ -1,5 +1,35 @@
|
||||
# `compiler_builtins_lib`
|
||||
|
||||
This feature is internal to the Rust compiler and is not intended for general use.
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
||||
This feature is required to link to the `compiler_builtins` crate which contains
|
||||
"compiler intrinsics". Compiler intrinsics are software implementations of basic
|
||||
operations like multiplication of `u64`s. These intrinsics are only required on
|
||||
platforms where these operations don't directly map to a hardware instruction.
|
||||
|
||||
You should never need to explicitly link to the `compiler_builtins` crate when
|
||||
building "std" programs as `compiler_builtins` is already in the dependency
|
||||
graph of `std`. But you may need it when building `no_std` **binary** crates. If
|
||||
you get a *linker* error like:
|
||||
|
||||
``` text
|
||||
$PWD/src/main.rs:11: undefined reference to `__aeabi_lmul'
|
||||
$PWD/src/main.rs:11: undefined reference to `__aeabi_uldivmod'
|
||||
```
|
||||
|
||||
That means that you need to link to this crate.
|
||||
|
||||
When you link to this crate, make sure it only appears once in your crate
|
||||
dependency graph. Also, it doesn't matter where in the dependency graph, you
|
||||
place the `compiler_builtins` crate.
|
||||
|
||||
<!-- NOTE(ignore) doctests don't support `no_std` binaries -->
|
||||
|
||||
``` rust,ignore
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![no_std]
|
||||
|
||||
extern crate compiler_builtins;
|
||||
```
|
||||
|
@ -1,6 +1,5 @@
|
||||
# `compiler_builtins`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
This feature is internal to the Rust compiler and is not intended for general use.
|
||||
|
||||
------------------------
|
||||
|
||||
|
@ -539,17 +539,16 @@ impl AtomicBool {
|
||||
// We can't use atomic_nand here because it can result in a bool with
|
||||
// an invalid value. This happens because the atomic operation is done
|
||||
// with an 8-bit integer internally, which would set the upper 7 bits.
|
||||
// So we just use a compare-exchange loop instead, which is what the
|
||||
// intrinsic actually expands to anyways on many platforms.
|
||||
let mut old = self.load(Relaxed);
|
||||
loop {
|
||||
let new = !(old && val);
|
||||
match self.compare_exchange_weak(old, new, order, Relaxed) {
|
||||
Ok(_) => break,
|
||||
Err(x) => old = x,
|
||||
}
|
||||
// So we just use fetch_xor or swap instead.
|
||||
if val {
|
||||
// !(x & true) == !x
|
||||
// We must invert the bool.
|
||||
self.fetch_xor(true, order)
|
||||
} else {
|
||||
// !(x & false) == true
|
||||
// We must set the bool to true.
|
||||
self.swap(true, order)
|
||||
}
|
||||
old
|
||||
}
|
||||
|
||||
/// Logical "or" with a boolean value.
|
||||
|
@ -24,10 +24,23 @@ fn bool_() {
|
||||
#[test]
|
||||
fn bool_and() {
|
||||
let a = AtomicBool::new(true);
|
||||
assert_eq!(a.fetch_and(false, SeqCst),true);
|
||||
assert_eq!(a.fetch_and(false, SeqCst), true);
|
||||
assert_eq!(a.load(SeqCst),false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bool_nand() {
|
||||
let a = AtomicBool::new(false);
|
||||
assert_eq!(a.fetch_nand(false, SeqCst), false);
|
||||
assert_eq!(a.load(SeqCst), true);
|
||||
assert_eq!(a.fetch_nand(false, SeqCst), true);
|
||||
assert_eq!(a.load(SeqCst), true);
|
||||
assert_eq!(a.fetch_nand(true, SeqCst), true);
|
||||
assert_eq!(a.load(SeqCst), false);
|
||||
assert_eq!(a.fetch_nand(true, SeqCst), false);
|
||||
assert_eq!(a.load(SeqCst), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_and() {
|
||||
let x = AtomicUsize::new(0xf731);
|
||||
|
@ -408,7 +408,7 @@ declare_features! (
|
||||
// Allows the definition recursive static items.
|
||||
(accepted, static_recursion, "1.17.0", Some(29719)),
|
||||
// pub(restricted) visibilities (RFC 1422)
|
||||
(accepted, pub_restricted, "1.17.0", Some(32409)),
|
||||
(accepted, pub_restricted, "1.18.0", Some(32409)),
|
||||
// The #![windows_subsystem] attribute
|
||||
(accepted, windows_subsystem, "1.18.0", Some(37499)),
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user