From 768e9029413c6fa3857cf8ba7d943bb297a58ee3 Mon Sep 17 00:00:00 2001 From: "A.J. Gardner" Date: Wed, 15 Mar 2017 21:27:40 -0500 Subject: First attempt at global_asm! macro --- src/libsyntax/ast.rs | 12 ++++++++++++ src/libsyntax/ext/expand.rs | 1 + src/libsyntax/feature_gate.rs | 6 ++++++ src/libsyntax/fold.rs | 10 ++++++++++ src/libsyntax/print/pprust.rs | 5 +++++ src/libsyntax/visit.rs | 6 ++++++ 6 files changed, 40 insertions(+) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c6a3e8a2ded..131adfe47af 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1585,6 +1585,15 @@ pub struct ForeignMod { pub items: Vec, } +/// Global inline assembly +/// +/// aka module-level assembly or file-scoped assembly +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub struct GlobalAsm { + pub asm: Symbol, + pub ctxt: SyntaxContext, +} + #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct EnumDef { pub variants: Vec, @@ -1812,6 +1821,8 @@ pub enum ItemKind { /// /// E.g. `extern {}` or `extern "C" {}` ForeignMod(ForeignMod), + /// Module-level inline assembly (from `global_asm!()`) + GlobalAsm(P), /// A type alias (`type` or `pub type`). /// /// E.g. `type Foo = Bar;` @@ -1864,6 +1875,7 @@ impl ItemKind { ItemKind::Fn(..) => "function", ItemKind::Mod(..) => "module", ItemKind::ForeignMod(..) => "foreign module", + ItemKind::GlobalAsm(..) => "global asm", ItemKind::Ty(..) => "type alias", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 1b3352f73ad..48bfc050223 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1039,6 +1039,7 @@ impl<'feat> ExpansionConfig<'feat> { feature_tests! { fn enable_quotes = quote, fn enable_asm = asm, + fn enable_global_asm = global_asm, fn enable_log_syntax = log_syntax, fn enable_concat_idents = concat_idents, fn enable_trace_macros = trace_macros, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 08762ccf04b..70e4f7a42b6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -346,6 +346,9 @@ declare_features! ( // Hack to document `-Z linker-flavor` in The Unstable Book (active, linker_flavor, "1.18.0", Some(41142)), + + // Allows module-level inline assembly by way of global_asm!() + (active, global_asm, "1.18.0", Some(35119)), ); declare_features! ( @@ -982,6 +985,9 @@ pub const EXPLAIN_STMT_ATTR_SYNTAX: &'static str = pub const EXPLAIN_ASM: &'static str = "inline assembly is not stable enough for use and is subject to change"; +pub const EXPLAIN_GLOBAL_ASM: &'static str = + "module-level inline assembly is experimental and subject to change"; + pub const EXPLAIN_LOG_SYNTAX: &'static str = "`log_syntax!` is not stable enough for use and is subject to change"; diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 92e25b00e0a..a6ab8e10d9f 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -140,6 +140,10 @@ pub trait Folder : Sized { noop_fold_foreign_mod(nm, self) } + fn fold_global_asm(&mut self, ga: P) -> P { + noop_fold_global_asm(ga, self) + } + fn fold_variant(&mut self, v: Variant) -> Variant { noop_fold_variant(v, self) } @@ -412,6 +416,11 @@ pub fn noop_fold_foreign_mod(ForeignMod {abi, items}: ForeignMod, } } +pub fn noop_fold_global_asm(ga: P, + _: &mut T) -> P { + ga +} + pub fn noop_fold_variant(v: Variant, fld: &mut T) -> Variant { Spanned { node: Variant_ { @@ -867,6 +876,7 @@ pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { } ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)), ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)), + ItemKind::GlobalAsm(ga) => ItemKind::GlobalAsm(folder.fold_global_asm(ga)), ItemKind::Ty(t, generics) => { ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics)) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e7feff2b79f..433ba3d3693 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1267,6 +1267,11 @@ impl<'a> State<'a> { self.print_foreign_mod(nmod, &item.attrs)?; self.bclose(item.span)?; } + ast::ItemKind::GlobalAsm(ref ga) => { + self.head(&visibility_qualified(&item.vis, "global_asm!"))?; + word(&mut self.s, &ga.asm.as_str())?; + self.end()?; + } ast::ItemKind::Ty(ref ty, ref params) => { self.ibox(INDENT_UNIT)?; self.ibox(0)?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index b5e9a1892ac..bae1c56db00 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -58,6 +58,7 @@ pub trait Visitor<'ast>: Sized { } fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _n: NodeId) { walk_mod(self, m) } fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { walk_foreign_item(self, i) } + fn visit_global_asm(&mut self, ga: &'ast GlobalAsm) { walk_global_asm(self, ga) } fn visit_item(&mut self, i: &'ast Item) { walk_item(self, i) } fn visit_local(&mut self, l: &'ast Local) { walk_local(self, l) } fn visit_block(&mut self, b: &'ast Block) { walk_block(self, b) } @@ -253,6 +254,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { ItemKind::ForeignMod(ref foreign_module) => { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } + ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga), ItemKind::Ty(ref typ, ref type_parameters) => { visitor.visit_ty(typ); visitor.visit_generics(type_parameters) @@ -464,6 +466,10 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, foreign_item: &'a walk_list!(visitor, visit_attribute, &foreign_item.attrs); } +pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) { + // Empty! +} + pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyParamBound) { match *bound { TraitTyParamBound(ref typ, ref modifier) => { -- cgit 1.4.1-3-g733a5 From da0742c0707225c796c1710d5f97b58a5bc5a864 Mon Sep 17 00:00:00 2001 From: "A.J. Gardner" Date: Tue, 21 Mar 2017 23:47:25 -0500 Subject: Add global_asm tests --- src/doc/unstable-book/src/global_asm.md | 2 +- src/librustc_driver/test.rs | 1 + src/libsyntax/feature_gate.rs | 2 +- src/test/codegen/foo.s | 3 + src/test/codegen/global_asm.rs | 73 +++++++++++++++++++ src/test/codegen/global_asm_include.rs | 68 ++++++++++++++++++ src/test/codegen/global_asm_x2.rs | 90 ++++++++++++++++++++++++ src/test/compile-fail/feature-gate-global_asm.rs | 15 ++++ src/test/run-pass/empty_global_asm.rs | 28 ++++++++ src/test/run-pass/simple_global_asm.rs | 27 +++++++ 10 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 src/test/codegen/foo.s create mode 100644 src/test/codegen/global_asm.rs create mode 100644 src/test/codegen/global_asm_include.rs create mode 100644 src/test/codegen/global_asm_x2.rs create mode 100644 src/test/compile-fail/feature-gate-global_asm.rs create mode 100644 src/test/run-pass/empty_global_asm.rs create mode 100644 src/test/run-pass/simple_global_asm.rs (limited to 'src/libsyntax') diff --git a/src/doc/unstable-book/src/global_asm.md b/src/doc/unstable-book/src/global_asm.md index f092a4ad664..44921aa309f 100644 --- a/src/doc/unstable-book/src/global_asm.md +++ b/src/doc/unstable-book/src/global_asm.md @@ -27,7 +27,7 @@ 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")); +global_asm!(include_str!("something_neato.s")); ``` And a more complicated usage looks like this: diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index af2416f787e..44e291a44c7 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -233,6 +233,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { hir::ItemStatic(..) | hir::ItemFn(..) | hir::ItemForeignMod(..) | + hir::ItemGlobalAsm(..) | hir::ItemTy(..) => None, hir::ItemEnum(..) | diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 70e4f7a42b6..8b62416dcbd 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -986,7 +986,7 @@ pub const EXPLAIN_ASM: &'static str = "inline assembly is not stable enough for use and is subject to change"; pub const EXPLAIN_GLOBAL_ASM: &'static str = - "module-level inline assembly is experimental and subject to change"; + "`global_asm!` is not stable enough for use and is subject to change"; pub const EXPLAIN_LOG_SYNTAX: &'static str = "`log_syntax!` is not stable enough for use and is subject to change"; diff --git a/src/test/codegen/foo.s b/src/test/codegen/foo.s new file mode 100644 index 00000000000..304d82aa0c6 --- /dev/null +++ b/src/test/codegen/foo.s @@ -0,0 +1,3 @@ +.global foo +foo: + jmp baz diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs new file mode 100644 index 00000000000..5bd0c1b4076 --- /dev/null +++ b/src/test/codegen/global_asm.rs @@ -0,0 +1,73 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-aarch64 +// ignore-aarch64_be +// ignore-arm +// ignore-armeb +// ignore-avr +// ignore-bpfel +// ignore-bpfeb +// ignore-hexagon +// ignore-mips +// ignore-mipsel +// ignore-mips64 +// ignore-mips64el +// ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-powerpc +// ignore-r600 +// ignore-amdgcn +// ignore-sparc +// ignore-sparcv9 +// ignore-sparcel +// ignore-s390x +// ignore-tce +// ignore-thumb +// ignore-thumbeb +// ignore-xcore +// ignore-nvptx +// ignore-nvptx64 +// ignore-le32 +// ignore-le64 +// ignore-amdil +// ignore-amdil64 +// ignore-hsail +// ignore-hsail64 +// ignore-spir +// ignore-spir64 +// ignore-kalimba +// ignore-shave +// ignore-wasm32 +// ignore-wasm64 +// ignore-emscripten +// compile-flags: -C no-prepopulate-passes + +#![feature(global_asm)] +#![crate_type = "lib"] + +// CHECK-LABEL: foo +// CHECK: module asm +// this regex will capture the correct unconditional branch inst. +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +global_asm!(r#" + .global foo +foo: + jmp baz +"#); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs new file mode 100644 index 00000000000..401b1fad566 --- /dev/null +++ b/src/test/codegen/global_asm_include.rs @@ -0,0 +1,68 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-aarch64 +// ignore-aarch64_be +// ignore-arm +// ignore-armeb +// ignore-avr +// ignore-bpfel +// ignore-bpfeb +// ignore-hexagon +// ignore-mips +// ignore-mipsel +// ignore-mips64 +// ignore-mips64el +// ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-powerpc +// ignore-r600 +// ignore-amdgcn +// ignore-sparc +// ignore-sparcv9 +// ignore-sparcel +// ignore-s390x +// ignore-tce +// ignore-thumb +// ignore-thumbeb +// ignore-xcore +// ignore-nvptx +// ignore-nvptx64 +// ignore-le32 +// ignore-le64 +// ignore-amdil +// ignore-amdil64 +// ignore-hsail +// ignore-hsail64 +// ignore-spir +// ignore-spir64 +// ignore-kalimba +// ignore-shave +// ignore-wasm32 +// ignore-wasm64 +// ignore-emscripten +// compile-flags: -C no-prepopulate-passes + +#![feature(global_asm)] +#![crate_type = "lib"] + +// CHECK-LABEL: foo +// CHECK: module asm +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +global_asm!(include_str!("foo.s")); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs new file mode 100644 index 00000000000..8b59165e9e6 --- /dev/null +++ b/src/test/codegen/global_asm_x2.rs @@ -0,0 +1,90 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-aarch64 +// ignore-aarch64_be +// ignore-arm +// ignore-armeb +// ignore-avr +// ignore-bpfel +// ignore-bpfeb +// ignore-hexagon +// ignore-mips +// ignore-mipsel +// ignore-mips64 +// ignore-mips64el +// ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-powerpc +// ignore-r600 +// ignore-amdgcn +// ignore-sparc +// ignore-sparcv9 +// ignore-sparcel +// ignore-s390x +// ignore-tce +// ignore-thumb +// ignore-thumbeb +// ignore-xcore +// ignore-nvptx +// ignore-nvptx64 +// ignore-le32 +// ignore-le64 +// ignore-amdil +// ignore-amdil64 +// ignore-hsail +// ignore-hsail64 +// ignore-spir +// ignore-spir64 +// ignore-kalimba +// ignore-shave +// ignore-wasm32 +// ignore-wasm64 +// ignore-emscripten +// compile-flags: -C no-prepopulate-passes + +#![feature(global_asm)] +#![crate_type = "lib"] +#[no_std] + +// CHECK-LABEL: foo +// CHECK: module asm +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +// any other global_asm will be appended to this first block, so: +// CHECK-LABEL: bar +// CHECK: module asm "{{[[:space:]]+}}jmp quux" +global_asm!(r#" + .global foo +foo: + jmp baz +"#); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} + +// no checks here; this has been appended to the first occurrence +global_asm!(r#" + .global bar +bar: + jmp quux +"#); + +extern "C" { + fn bar(); +} + +#[no_mangle] +pub unsafe extern "C" fn quux() {} diff --git a/src/test/compile-fail/feature-gate-global_asm.rs b/src/test/compile-fail/feature-gate-global_asm.rs new file mode 100644 index 00000000000..0560abb6af4 --- /dev/null +++ b/src/test/compile-fail/feature-gate-global_asm.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// gate-test-global_asm + +global_asm!(""); //~ ERROR `global_asm!` is not stable + +fn main() {} diff --git a/src/test/run-pass/empty_global_asm.rs b/src/test/run-pass/empty_global_asm.rs new file mode 100644 index 00000000000..db73da2747f --- /dev/null +++ b/src/test/run-pass/empty_global_asm.rs @@ -0,0 +1,28 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(global_asm)] + +#[cfg(target_arch = "x86")] +global_asm!(""); + +#[cfg(target_arch = "x86_64")] +global_asm!(""); + +#[cfg(target_arch = "arm")] +global_asm!(""); + +#[cfg(target_arch = "aarch64")] +global_asm!(""); + +#[cfg(target_arch = "mips")] +global_asm!(""); + +fn main() {} diff --git a/src/test/run-pass/simple_global_asm.rs b/src/test/run-pass/simple_global_asm.rs new file mode 100644 index 00000000000..a5ffe607fdf --- /dev/null +++ b/src/test/run-pass/simple_global_asm.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(global_asm)] + +#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] +global_asm!(r#" + .global foo +foo: + jmp baz +"#); + +extern { + fn foo(); +} + +#[no_mangle] +pub extern fn baz() {} + +fn main() {} -- cgit 1.4.1-3-g733a5