Merge pull request #163 from yvt/fix-asm-sym
Add inline assembly `sym` operands as GCC input operands
This commit is contained in:
commit
0405aa0065
6 changed files with 68 additions and 9 deletions
|
@ -9,8 +9,12 @@ license = "MIT OR Apache-2.0"
|
|||
crate-type = ["dylib"]
|
||||
|
||||
[[test]]
|
||||
name = "lang_tests"
|
||||
path = "tests/lib.rs"
|
||||
name = "lang_tests_debug"
|
||||
path = "tests/lang_tests_debug.rs"
|
||||
harness = false
|
||||
[[test]]
|
||||
name = "lang_tests_release"
|
||||
path = "tests/lang_tests_release.rs"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
|
|
22
src/asm.rs
22
src/asm.rs
|
@ -13,6 +13,7 @@ use std::borrow::Cow;
|
|||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
use crate::type_of::LayoutGccExt;
|
||||
use crate::callee::get_fn;
|
||||
|
||||
|
||||
// Rust asm! and GCC Extended Asm semantics differ substantially.
|
||||
|
@ -342,9 +343,24 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
// processed in the previous pass
|
||||
}
|
||||
|
||||
InlineAsmOperandRef::Const { .. }
|
||||
| InlineAsmOperandRef::SymFn { .. }
|
||||
| InlineAsmOperandRef::SymStatic { .. } => {
|
||||
InlineAsmOperandRef::SymFn { instance } => {
|
||||
inputs.push(AsmInOperand {
|
||||
constraint: "X".into(),
|
||||
rust_idx,
|
||||
val: self.cx.rvalue_as_function(get_fn(self.cx, instance))
|
||||
.get_address(None),
|
||||
});
|
||||
}
|
||||
|
||||
InlineAsmOperandRef::SymStatic { def_id } => {
|
||||
inputs.push(AsmInOperand {
|
||||
constraint: "X".into(),
|
||||
rust_idx,
|
||||
val: self.cx.get_static(def_id).get_address(None),
|
||||
});
|
||||
}
|
||||
|
||||
InlineAsmOperandRef::Const { .. } => {
|
||||
// processed in the previous pass
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//! The common code for `tests/lang_tests_*.rs`
|
||||
use std::{
|
||||
env::{self, current_dir},
|
||||
path::PathBuf,
|
||||
|
@ -7,7 +8,15 @@ use std::{
|
|||
use lang_tester::LangTester;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn main() {
|
||||
/// Controls the compile options (e.g., optimization level) used to compile
|
||||
/// test code.
|
||||
#[allow(dead_code)] // Each test crate picks one variant
|
||||
pub enum Profile {
|
||||
Debug,
|
||||
Release,
|
||||
}
|
||||
|
||||
pub fn main_inner(profile: Profile) {
|
||||
let tempdir = TempDir::new().expect("temp dir");
|
||||
let current_dir = current_dir().expect("current dir");
|
||||
let current_dir = current_dir.to_str().expect("current dir").to_string();
|
||||
|
@ -42,6 +51,15 @@ fn main() {
|
|||
"-o", exe.to_str().expect("to_str"),
|
||||
path.to_str().expect("to_str"),
|
||||
]);
|
||||
match profile {
|
||||
Profile::Debug => {}
|
||||
Profile::Release => {
|
||||
compiler.args(&[
|
||||
"-C", "opt-level=3",
|
||||
"-C", "lto=no",
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Test command 2: run `tempdir/x`.
|
||||
let runtime = Command::new(exe);
|
||||
vec![("Compiler", compiler), ("Run-time", runtime)]
|
5
tests/lang_tests_debug.rs
Normal file
5
tests/lang_tests_debug.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod lang_tests_common;
|
||||
|
||||
fn main() {
|
||||
lang_tests_common::main_inner(lang_tests_common::Profile::Debug);
|
||||
}
|
5
tests/lang_tests_release.rs
Normal file
5
tests/lang_tests_release.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod lang_tests_common;
|
||||
|
||||
fn main() {
|
||||
lang_tests_common::main_inner(lang_tests_common::Profile::Release);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// Compiler:
|
||||
//
|
||||
// Run-time:
|
||||
// stdout: Panicking
|
||||
// stdout: Success
|
||||
// status: signal
|
||||
|
||||
#![allow(unused_attributes)]
|
||||
|
@ -64,7 +64,9 @@ mod intrinsics {
|
|||
#[no_mangle]
|
||||
pub fn panic(_msg: &str) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\0" as *const str as *const u8);
|
||||
// Panicking is expected iff overflow checking is enabled.
|
||||
#[cfg(debug_assertions)]
|
||||
libc::puts("Success\0" as *const str as *const u8);
|
||||
libc::fflush(libc::stdout);
|
||||
intrinsics::abort();
|
||||
}
|
||||
|
@ -124,6 +126,15 @@ impl Add for isize {
|
|||
#[start]
|
||||
fn main(mut argc: isize, _argv: *const *const u8) -> isize {
|
||||
let int = 9223372036854775807isize;
|
||||
let int = int + argc;
|
||||
let int = int + argc; // overflow
|
||||
|
||||
// If overflow checking is disabled, we should reach here.
|
||||
#[cfg(not(debug_assertions))]
|
||||
unsafe {
|
||||
libc::puts("Success\0" as *const str as *const u8);
|
||||
libc::fflush(libc::stdout);
|
||||
intrinsics::abort();
|
||||
}
|
||||
|
||||
int
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue