From cf46fb1945ac51048b327a84a0b23ae9ec82b35a Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 27 Apr 2021 21:18:01 -0500 Subject: [PATCH 1/5] unignore a couple of tests --- src/test/ui/or-patterns/macro-pat.rs | 2 -- src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/test/ui/or-patterns/macro-pat.rs b/src/test/ui/or-patterns/macro-pat.rs index 8c581b630dece..806d1901702ff 100644 --- a/src/test/ui/or-patterns/macro-pat.rs +++ b/src/test/ui/or-patterns/macro-pat.rs @@ -1,7 +1,5 @@ // run-pass // edition:2021 -// ignore-test -// FIXME(mark-i-m): enable this test again when 2021 machinery is available use Foo::*; diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs index f0ce7597aeed1..c0d148d92042f 100644 --- a/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs +++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs @@ -1,9 +1,7 @@ // Tests that :pat in macros in edition 2021 allows top-level or-patterns. // run-pass -// ignore-test // edition:2021 -// FIXME(mark-i-m): unignore when 2021 machinery is in place. macro_rules! accept_pat { ($p:pat) => {}; From 26fb1e373bd313b70d1f95cd16259035e5a7f8c8 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Sat, 24 Apr 2021 17:50:40 +0200 Subject: [PATCH 2/5] Reuse `unix::cmath` --- library/std/src/sys/hermit/cmath.rs | 29 ------------- library/std/src/sys/hermit/mod.rs | 1 + library/std/src/sys/sgx/cmath.rs | 31 ------------- library/std/src/sys/sgx/mod.rs | 1 + library/std/src/sys/unix/cmath.rs | 55 ++++++++++++------------ library/std/src/sys/unix/mod.rs | 1 + library/std/src/sys/unsupported/cmath.rs | 29 ------------- library/std/src/sys/unsupported/mod.rs | 1 + library/std/src/sys/wasi/mod.rs | 2 +- library/std/src/sys/wasm/mod.rs | 2 +- 10 files changed, 34 insertions(+), 118 deletions(-) delete mode 100644 library/std/src/sys/hermit/cmath.rs delete mode 100644 library/std/src/sys/sgx/cmath.rs delete mode 100644 library/std/src/sys/unsupported/cmath.rs diff --git a/library/std/src/sys/hermit/cmath.rs b/library/std/src/sys/hermit/cmath.rs deleted file mode 100644 index 304cf906b2aea..0000000000000 --- a/library/std/src/sys/hermit/cmath.rs +++ /dev/null @@ -1,29 +0,0 @@ -// These symbols are all defined in `compiler-builtins` -extern "C" { - pub fn acos(n: f64) -> f64; - pub fn acosf(n: f32) -> f32; - pub fn asin(n: f64) -> f64; - pub fn asinf(n: f32) -> f32; - pub fn atan(n: f64) -> f64; - pub fn atan2(a: f64, b: f64) -> f64; - pub fn atan2f(a: f32, b: f32) -> f32; - pub fn atanf(n: f32) -> f32; - pub fn cbrt(n: f64) -> f64; - pub fn cbrtf(n: f32) -> f32; - pub fn cosh(n: f64) -> f64; - pub fn coshf(n: f32) -> f32; - pub fn expm1(n: f64) -> f64; - pub fn expm1f(n: f32) -> f32; - pub fn fdim(a: f64, b: f64) -> f64; - pub fn fdimf(a: f32, b: f32) -> f32; - pub fn hypot(x: f64, y: f64) -> f64; - pub fn hypotf(x: f32, y: f32) -> f32; - pub fn log1p(n: f64) -> f64; - pub fn log1pf(n: f32) -> f32; - pub fn sinh(n: f64) -> f64; - pub fn sinhf(n: f32) -> f32; - pub fn tan(n: f64) -> f64; - pub fn tanf(n: f32) -> f32; - pub fn tanh(n: f64) -> f64; - pub fn tanhf(n: f32) -> f32; -} diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 56497162c0333..941e8bc7a66bf 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -20,6 +20,7 @@ use crate::os::raw::c_char; pub mod alloc; pub mod args; +#[path = "../unix/cmath.rs"] pub mod cmath; pub mod condvar; pub mod env; diff --git a/library/std/src/sys/sgx/cmath.rs b/library/std/src/sys/sgx/cmath.rs deleted file mode 100644 index b89238f1da8f7..0000000000000 --- a/library/std/src/sys/sgx/cmath.rs +++ /dev/null @@ -1,31 +0,0 @@ -#![cfg(not(test))] - -// These symbols are all defined in `compiler-builtins` -extern "C" { - pub fn acos(n: f64) -> f64; - pub fn acosf(n: f32) -> f32; - pub fn asin(n: f64) -> f64; - pub fn asinf(n: f32) -> f32; - pub fn atan(n: f64) -> f64; - pub fn atan2(a: f64, b: f64) -> f64; - pub fn atan2f(a: f32, b: f32) -> f32; - pub fn atanf(n: f32) -> f32; - pub fn cbrt(n: f64) -> f64; - pub fn cbrtf(n: f32) -> f32; - pub fn cosh(n: f64) -> f64; - pub fn coshf(n: f32) -> f32; - pub fn expm1(n: f64) -> f64; - pub fn expm1f(n: f32) -> f32; - pub fn fdim(a: f64, b: f64) -> f64; - pub fn fdimf(a: f32, b: f32) -> f32; - pub fn hypot(x: f64, y: f64) -> f64; - pub fn hypotf(x: f32, y: f32) -> f32; - pub fn log1p(n: f64) -> f64; - pub fn log1pf(n: f32) -> f32; - pub fn sinh(n: f64) -> f64; - pub fn sinhf(n: f32) -> f32; - pub fn tan(n: f64) -> f64; - pub fn tanf(n: f32) -> f32; - pub fn tanh(n: f64) -> f64; - pub fn tanhf(n: f32) -> f32; -} diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs index d6a5683073309..276ac81773132 100644 --- a/library/std/src/sys/sgx/mod.rs +++ b/library/std/src/sys/sgx/mod.rs @@ -13,6 +13,7 @@ mod waitqueue; pub mod alloc; pub mod args; +#[path = "../unix/cmath.rs"] pub mod cmath; pub mod condvar; pub mod env; diff --git a/library/std/src/sys/unix/cmath.rs b/library/std/src/sys/unix/cmath.rs index f327b69fc7541..2bf80d7a4cbe2 100644 --- a/library/std/src/sys/unix/cmath.rs +++ b/library/std/src/sys/unix/cmath.rs @@ -1,32 +1,33 @@ #![cfg(not(test))] -use libc::{c_double, c_float}; +// These symbols are all defined by `libm`, +// or by `compiler-builtins` on unsupported platforms. extern "C" { - pub fn acos(n: c_double) -> c_double; - pub fn acosf(n: c_float) -> c_float; - pub fn asin(n: c_double) -> c_double; - pub fn asinf(n: c_float) -> c_float; - pub fn atan(n: c_double) -> c_double; - pub fn atan2(a: c_double, b: c_double) -> c_double; - pub fn atan2f(a: c_float, b: c_float) -> c_float; - pub fn atanf(n: c_float) -> c_float; - pub fn cbrt(n: c_double) -> c_double; - pub fn cbrtf(n: c_float) -> c_float; - pub fn cosh(n: c_double) -> c_double; - pub fn coshf(n: c_float) -> c_float; - pub fn expm1(n: c_double) -> c_double; - pub fn expm1f(n: c_float) -> c_float; - pub fn fdim(a: c_double, b: c_double) -> c_double; - pub fn fdimf(a: c_float, b: c_float) -> c_float; - pub fn hypot(x: c_double, y: c_double) -> c_double; - pub fn hypotf(x: c_float, y: c_float) -> c_float; - pub fn log1p(n: c_double) -> c_double; - pub fn log1pf(n: c_float) -> c_float; - pub fn sinh(n: c_double) -> c_double; - pub fn sinhf(n: c_float) -> c_float; - pub fn tan(n: c_double) -> c_double; - pub fn tanf(n: c_float) -> c_float; - pub fn tanh(n: c_double) -> c_double; - pub fn tanhf(n: c_float) -> c_float; + pub fn acos(n: f64) -> f64; + pub fn acosf(n: f32) -> f32; + pub fn asin(n: f64) -> f64; + pub fn asinf(n: f32) -> f32; + pub fn atan(n: f64) -> f64; + pub fn atan2(a: f64, b: f64) -> f64; + pub fn atan2f(a: f32, b: f32) -> f32; + pub fn atanf(n: f32) -> f32; + pub fn cbrt(n: f64) -> f64; + pub fn cbrtf(n: f32) -> f32; + pub fn cosh(n: f64) -> f64; + pub fn coshf(n: f32) -> f32; + pub fn expm1(n: f64) -> f64; + pub fn expm1f(n: f32) -> f32; + pub fn fdim(a: f64, b: f64) -> f64; + pub fn fdimf(a: f32, b: f32) -> f32; + pub fn hypot(x: f64, y: f64) -> f64; + pub fn hypotf(x: f32, y: f32) -> f32; + pub fn log1p(n: f64) -> f64; + pub fn log1pf(n: f32) -> f32; + pub fn sinh(n: f64) -> f64; + pub fn sinhf(n: f32) -> f32; + pub fn tan(n: f64) -> f64; + pub fn tanf(n: f32) -> f32; + pub fn tanh(n: f64) -> f64; + pub fn tanhf(n: f32) -> f32; } diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 1316835a89d12..d19322355061e 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -11,6 +11,7 @@ pub mod weak; pub mod alloc; pub mod android; pub mod args; +#[path = "../unix/cmath.rs"] pub mod cmath; pub mod condvar; pub mod env; diff --git a/library/std/src/sys/unsupported/cmath.rs b/library/std/src/sys/unsupported/cmath.rs deleted file mode 100644 index 304cf906b2aea..0000000000000 --- a/library/std/src/sys/unsupported/cmath.rs +++ /dev/null @@ -1,29 +0,0 @@ -// These symbols are all defined in `compiler-builtins` -extern "C" { - pub fn acos(n: f64) -> f64; - pub fn acosf(n: f32) -> f32; - pub fn asin(n: f64) -> f64; - pub fn asinf(n: f32) -> f32; - pub fn atan(n: f64) -> f64; - pub fn atan2(a: f64, b: f64) -> f64; - pub fn atan2f(a: f32, b: f32) -> f32; - pub fn atanf(n: f32) -> f32; - pub fn cbrt(n: f64) -> f64; - pub fn cbrtf(n: f32) -> f32; - pub fn cosh(n: f64) -> f64; - pub fn coshf(n: f32) -> f32; - pub fn expm1(n: f64) -> f64; - pub fn expm1f(n: f32) -> f32; - pub fn fdim(a: f64, b: f64) -> f64; - pub fn fdimf(a: f32, b: f32) -> f32; - pub fn hypot(x: f64, y: f64) -> f64; - pub fn hypotf(x: f32, y: f32) -> f32; - pub fn log1p(n: f64) -> f64; - pub fn log1pf(n: f32) -> f32; - pub fn sinh(n: f64) -> f64; - pub fn sinhf(n: f32) -> f32; - pub fn tan(n: f64) -> f64; - pub fn tanf(n: f32) -> f32; - pub fn tanh(n: f64) -> f64; - pub fn tanhf(n: f32) -> f32; -} diff --git a/library/std/src/sys/unsupported/mod.rs b/library/std/src/sys/unsupported/mod.rs index d9efdec33d937..43cdad004468d 100644 --- a/library/std/src/sys/unsupported/mod.rs +++ b/library/std/src/sys/unsupported/mod.rs @@ -2,6 +2,7 @@ pub mod alloc; pub mod args; +#[path = "../unix/cmath.rs"] pub mod cmath; pub mod condvar; pub mod env; diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index b7b640b174fa9..25213fa274244 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -20,7 +20,7 @@ use crate::mem; #[path = "../unix/alloc.rs"] pub mod alloc; pub mod args; -#[path = "../unsupported/cmath.rs"] +#[path = "../unix/cmath.rs"] pub mod cmath; #[path = "../unsupported/condvar.rs"] pub mod condvar; diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 82683c0f624cf..bb7ef4f13819d 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -18,7 +18,7 @@ pub mod alloc; pub mod args; -#[path = "../unsupported/cmath.rs"] +#[path = "../unix/cmath.rs"] pub mod cmath; pub mod env; #[path = "../unsupported/fs.rs"] From e6a731eb90fe3d47d89416e199832af4248399f6 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 28 Apr 2021 16:28:59 +0100 Subject: [PATCH 3/5] Be stricter about rejecting LLVM reserved registers in asm! --- compiler/rustc_target/src/asm/aarch64.rs | 10 +++--- compiler/rustc_target/src/asm/arm.rs | 3 +- compiler/rustc_target/src/asm/hexagon.rs | 3 +- compiler/rustc_target/src/asm/riscv.rs | 3 +- compiler/rustc_target/src/asm/x86.rs | 32 +++++++++++++++++-- .../unstable-book/src/library-features/asm.md | 25 ++++++++------- src/test/codegen/asm-multiple-options.rs | 2 +- src/test/codegen/asm-options.rs | 2 +- src/test/pretty/asm.pp | 2 +- src/test/pretty/asm.rs | 2 +- 10 files changed, 59 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index e7c9edea7653a..dd51574efca0a 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -83,10 +83,8 @@ def_regs! { x13: reg = ["x13", "w13"], x14: reg = ["x14", "w14"], x15: reg = ["x15", "w15"], - x16: reg = ["x16", "w16"], x17: reg = ["x17", "w17"], x18: reg = ["x18", "w18"], - x19: reg = ["x19", "w19"], x20: reg = ["x20", "w20"], x21: reg = ["x21", "w21"], x22: reg = ["x22", "w22"], @@ -96,7 +94,7 @@ def_regs! { x26: reg = ["x26", "w26"], x27: reg = ["x27", "w27"], x28: reg = ["x28", "w28"], - x30: reg = ["x30", "w30", "lr"], + x30: reg = ["x30", "w30", "lr", "wlr"], v0: vreg, vreg_low16 = ["v0", "b0", "h0", "s0", "d0", "q0"], v1: vreg, vreg_low16 = ["v1", "b1", "h1", "s1", "d1", "q1"], v2: vreg, vreg_low16 = ["v2", "b2", "h2", "s2", "d2", "q2"], @@ -129,7 +127,11 @@ def_regs! { v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29"], v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30"], v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31"], - #error = ["x29", "fp"] => + #error = ["x16", "w16"] => + "x16 is used internally by LLVM and cannot be used as an operand for inline asm", + #error = ["x19", "w19"] => + "x19 is used internally by LLVM and cannot be used as an operand for inline asm", + #error = ["x29", "w29", "fp", "wfp"] => "the frame pointer cannot be used as an operand for inline asm", #error = ["sp", "wsp"] => "the stack pointer cannot be used as an operand for inline asm", diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index a7a708fe7dec3..4c323fc35d643 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -98,7 +98,6 @@ def_regs! { r5: reg, reg_thumb = ["r5", "v2"], r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7, r8: reg = ["r8", "v5"], - r9: reg = ["r9", "v6", "rfp"], r10: reg = ["r10", "sl"], r11: reg = ["r11", "fp"] % frame_pointer_r11, r12: reg = ["r12", "ip"], @@ -185,6 +184,8 @@ def_regs! { q15: qreg = ["q15"], #error = ["r6", "v3"] => "r6 is used internally by LLVM and cannot be used as an operand for inline asm", + #error = ["r9", "v6", "rfp"] => + "r9 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r13", "sp"] => "the stack pointer cannot be used as an operand for inline asm", #error = ["r15", "pc"] => diff --git a/compiler/rustc_target/src/asm/hexagon.rs b/compiler/rustc_target/src/asm/hexagon.rs index d41941d0b4cd7..74afddb69dc75 100644 --- a/compiler/rustc_target/src/asm/hexagon.rs +++ b/compiler/rustc_target/src/asm/hexagon.rs @@ -60,7 +60,6 @@ def_regs! { r16: reg = ["r16"], r17: reg = ["r17"], r18: reg = ["r18"], - r19: reg = ["r19"], r20: reg = ["r20"], r21: reg = ["r21"], r22: reg = ["r22"], @@ -70,6 +69,8 @@ def_regs! { r26: reg = ["r26"], r27: reg = ["r27"], r28: reg = ["r28"], + #error = ["r19"] => + "r19 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["r29", "sp"] => "the stack pointer cannot be used as an operand for inline asm", #error = ["r30", "fr"] => diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index 185d6ac8246c9..e276a9175f9ab 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -66,7 +66,6 @@ def_regs! { x5: reg = ["x5", "t0"], x6: reg = ["x6", "t1"], x7: reg = ["x7", "t2"], - x9: reg = ["x9", "s1"], x10: reg = ["x10", "a0"], x11: reg = ["x11", "a1"], x12: reg = ["x12", "a2"], @@ -121,6 +120,8 @@ def_regs! { f29: freg = ["f29", "ft9"], f30: freg = ["f30", "ft10"], f31: freg = ["f31", "ft11"], + #error = ["x9", "s1"] => + "s1 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["x8", "s0", "fp"] => "the frame pointer cannot be used as an operand for inline asm", #error = ["x2", "sp"] => diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 90660dad4c2a1..48f83ca7cd49a 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -152,13 +152,41 @@ fn high_byte( } } +fn rbx_reserved( + arch: InlineAsmArch, + _has_feature: impl FnMut(&str) -> bool, + _target: &Target, +) -> Result<(), &'static str> { + match arch { + InlineAsmArch::X86 => Ok(()), + InlineAsmArch::X86_64 => { + Err("rbx is used internally by LLVM and cannot be used as an operand for inline asm") + } + _ => unreachable!(), + } +} + +fn esi_reserved( + arch: InlineAsmArch, + _has_feature: impl FnMut(&str) -> bool, + _target: &Target, +) -> Result<(), &'static str> { + match arch { + InlineAsmArch::X86 => { + Err("esi is used internally by LLVM and cannot be used as an operand for inline asm") + } + InlineAsmArch::X86_64 => Ok(()), + _ => unreachable!(), + } +} + def_regs! { X86 X86InlineAsmReg X86InlineAsmRegClass { ax: reg, reg_abcd = ["ax", "eax", "rax"], - bx: reg, reg_abcd = ["bx", "ebx", "rbx"], + bx: reg, reg_abcd = ["bx", "ebx", "rbx"] % rbx_reserved, cx: reg, reg_abcd = ["cx", "ecx", "rcx"], dx: reg, reg_abcd = ["dx", "edx", "rdx"], - si: reg = ["si", "esi", "rsi"], + si: reg = ["si", "esi", "rsi"] % esi_reserved, di: reg = ["di", "edi", "rdi"], r8: reg = ["r8", "r8w", "r8d"] % x86_64_only, r9: reg = ["r9", "r9w", "r9d"] % x86_64_only, diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 4f9033cedc3ff..7c2bf62185530 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -535,20 +535,20 @@ Here is the list of currently supported register classes: | Architecture | Register class | Registers | LLVM constraint code | | ------------ | -------------- | --------- | -------------------- | -| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `r[8-15]` (x86-64 only) | `r` | +| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `bp`, `r[8-15]` (x86-64 only) | `r` | | x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` | | x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` | -| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `r[8-15]b` | `q` | +| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `bpl`, `r[8-15]b` | `q` | | x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` | | x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` | | x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` | | x86 | `kreg` | `k[1-7]` | `Yk` | -| AArch64 | `reg` | `x[0-28]`, `x30` | `r` | +| AArch64 | `reg` | `x[0-30]` | `r` | | AArch64 | `vreg` | `v[0-31]` | `w` | | AArch64 | `vreg_low16` | `v[0-15]` | `x` | -| ARM | `reg` | `r[0-5]` `r7`\*, `r[8-10]`, `r11`\*, `r12`, `r14` | `r` | +| ARM | `reg` | `r[0-12]`, `r14` | `r` | | ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` | -| ARM (ARM) | `reg_thumb` | `r[0-r10]`, `r12`, `r14` | `l` | +| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` | | ARM | `sreg` | `s[0-31]` | `t` | | ARM | `sreg_low16` | `s[0-15]` | `x` | | ARM | `dreg` | `d[0-31]` | `w` | @@ -573,9 +573,7 @@ Here is the list of currently supported register classes: > > Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported. > -> Note #4: On ARM the frame pointer is either `r7` or `r11` depending on the platform. -> -> Note #5: WebAssembly doesn't have registers, so named registers are not supported. +> Note #4: WebAssembly doesn't have registers, so named registers are not supported. Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc). @@ -677,13 +675,15 @@ Some registers cannot be used for input or output operands: | All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | | All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS) | The frame pointer cannot be used as an input or output. | | ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. | -| ARM | `r6` | `r6` is used internally by LLVM as a base pointer and therefore cannot be used as an input or output. | +| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `r19` (Hexagon), `x9` (RISC-V) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | | x86 | `k0` | This is a constant zero register which can't be modified. | | x86 | `ip` | This is the program counter, not a real register. | | x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). | | x86 | `st([0-7])` | x87 registers are not currently supported (but may be in the future). | | AArch64 | `xzr` | This is a constant zero register which can't be modified. | +| AArch64 | `x16` | This is used internally by LLVM for speculative load hardening. | | ARM | `pc` | This is the program counter, not a real register. | +| ARM | `r9` | This is a reserved register on some ARM targets. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | @@ -693,9 +693,10 @@ Some registers cannot be used for input or output operands: | RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. | | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | -In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are: -- The frame pointer on all architectures. -- `r6` on ARM. +In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are the frame pointer and base pointer +- The frame pointer and LLVM base pointer on all architectures. +- `x16` on AArch64. +- `r6` and `r9` on ARM. ## Template modifiers diff --git a/src/test/codegen/asm-multiple-options.rs b/src/test/codegen/asm-multiple-options.rs index c702742bf1a63..baf9f3e9bd14d 100644 --- a/src/test/codegen/asm-multiple-options.rs +++ b/src/test/codegen/asm-multiple-options.rs @@ -10,7 +10,7 @@ #[no_mangle] pub unsafe fn pure(x: i32) { let y: i32; - asm!("", out("ax") y, in("bx") x, options(pure), options(nomem)); + asm!("", out("ax") y, in("cx") x, options(pure), options(nomem)); } pub static mut VAR: i32 = 0; diff --git a/src/test/codegen/asm-options.rs b/src/test/codegen/asm-options.rs index 21e7eb4379634..70391661b0cfb 100644 --- a/src/test/codegen/asm-options.rs +++ b/src/test/codegen/asm-options.rs @@ -10,7 +10,7 @@ #[no_mangle] pub unsafe fn pure(x: i32) { let y: i32; - asm!("", out("ax") y, in("bx") x, options(pure, nomem)); + asm!("", out("ax") y, in("cx") x, options(pure, nomem)); } // CHECK-LABEL: @noreturn diff --git a/src/test/pretty/asm.pp b/src/test/pretty/asm.pp index c86d8a1197188..a2065039692b7 100644 --- a/src/test/pretty/asm.pp +++ b/src/test/pretty/asm.pp @@ -21,7 +21,7 @@ asm!("{0}", out(reg) a); asm!("{0}", inout(reg) b); asm!("{0} {1}", out(reg) _, inlateout(reg) b => _); - asm!("", out("al") _, lateout("rbx") _); + asm!("", out("al") _, lateout("rcx") _); asm!("inst1\ninst2"); asm!("inst1 {0}, 42\ninst2 {1}, 24", in(reg) a, out(reg) b); asm!("inst2 {1}, 24\ninst1 {0}, 42", in(reg) a, out(reg) b); diff --git a/src/test/pretty/asm.rs b/src/test/pretty/asm.rs index 33f25e5216b4e..1156ab769a043 100644 --- a/src/test/pretty/asm.rs +++ b/src/test/pretty/asm.rs @@ -15,7 +15,7 @@ pub fn main() { asm!("{0}", out(reg) a); asm!("{name}", name = inout(reg) b); asm!("{} {}", out(reg) _, inlateout(reg) b => _); - asm!("", out("al") _, lateout("rbx") _); + asm!("", out("al") _, lateout("rcx") _); asm!("inst1", "inst2"); asm!("inst1 {}, 42", "inst2 {}, 24", in(reg) a, out(reg) b); asm!("inst2 {1}, 24", "inst1 {0}, 42", in(reg) a, out(reg) b); From 6697b0d0f61ececf381800e14b4a6720e36e98b9 Mon Sep 17 00:00:00 2001 From: mark Date: Wed, 28 Apr 2021 20:51:32 -0500 Subject: [PATCH 4/5] fix test --- src/test/ui/or-patterns/macro-pat.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/or-patterns/macro-pat.rs b/src/test/ui/or-patterns/macro-pat.rs index 806d1901702ff..20d8f84c24743 100644 --- a/src/test/ui/or-patterns/macro-pat.rs +++ b/src/test/ui/or-patterns/macro-pat.rs @@ -3,6 +3,7 @@ use Foo::*; +#[allow(dead_code)] #[derive(Eq, PartialEq, Debug)] enum Foo { A(u64), From c064b6560b7ce0adeb9bbf5d7dcf12b1acb0c807 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Thu, 29 Apr 2021 16:15:50 +0000 Subject: [PATCH 5/5] [Arm64] use isb instruction instead of yield in spin loops On arm64 we have seen on several databases that ISB (instruction synchronization barrier) is better to use than yield in a spin loop. The yield instruction is a nop. The isb instruction puts the processor to sleep for some short time. isb is a good equivalent to the pause instruction on x86. Below is an experiment that shows the effects of yield and isb on Arm64 and the time of a pause instruction on x86 Intel processors. The micro-benchmarks use https://github.com/google/benchmark.git $ cat a.cc static void BM_scalar_increment(benchmark::State& state) { int i = 0; for (auto _ : state) benchmark::DoNotOptimize(i++); } BENCHMARK(BM_scalar_increment); static void BM_yield(benchmark::State& state) { for (auto _ : state) asm volatile("yield"::); } BENCHMARK(BM_yield); static void BM_isb(benchmark::State& state) { for (auto _ : state) asm volatile("isb"::); } BENCHMARK(BM_isb); BENCHMARK_MAIN(); $ g++ -o run a.cc -O2 -lbenchmark -lpthread $ ./run -------------------------------------------------------------- Benchmark Time CPU Iterations -------------------------------------------------------------- AWS Graviton2 (Neoverse-N1) processor: BM_scalar_increment 0.485 ns 0.485 ns 1000000000 BM_yield 0.400 ns 0.400 ns 1000000000 BM_isb 13.2 ns 13.2 ns 52993304 AWS Graviton (A-72) processor: BM_scalar_increment 0.897 ns 0.874 ns 801558633 BM_yield 0.877 ns 0.875 ns 800002377 BM_isb 13.0 ns 12.7 ns 55169412 Apple Arm64 M1 processor: BM_scalar_increment 0.315 ns 0.315 ns 1000000000 BM_yield 0.313 ns 0.313 ns 1000000000 BM_isb 9.06 ns 9.06 ns 77259282 static void BM_pause(benchmark::State& state) { for (auto _ : state) asm volatile("pause"::); } BENCHMARK(BM_pause); Intel Skylake processor: BM_scalar_increment 0.295 ns 0.295 ns 1000000000 BM_pause 41.7 ns 41.7 ns 16780553 Tested on Graviton2 aarch64-linux with `./x.py test`. --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 313729581acd9..8e7c95abd6872 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -128,7 +128,7 @@ pub fn spin_loop() { #[cfg(target_arch = "aarch64")] { // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets. - unsafe { crate::arch::aarch64::__yield() }; + unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) }; } #[cfg(target_arch = "arm")] {