-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #38726 - japaric:sparc64, r=sanxiyn
sparc64-linux support This is built on top of #38656 and depends on rust-lang/libc#483 Hello world works. The libc-test test suite passes. `panic!` doesn't fully work: ``` $ qemu-sparc64-static ./panic thread 'main' panicked at 'explicit panic', panic.rs:1 note: Run with `RUST_BACKTRACE=1` for a backtrace. Illegal instruction (core dumped) ``` Backtraces don't work either, probably related to the previous point: ``` $ export RUST_BACKTRACE=1 $ qemu-sparc64-static ./panic thread 'main' panicked at 'explicit panic', panic.rs:1 stack backtrace: Illegal instruction (core dumped) ``` r? @alexcrichton @jakllsch Does panicking / backtraces work on sparc64-netbsd? cc @glaubitz
- Loading branch information
Showing
19 changed files
with
291 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# rustbuild-only target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# This file is intentially left empty to indicate that, while this target is | ||
# supported, it's not supported using plain GNU Make builds. Use a --rustbuild | ||
# instead. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule liblibc
updated
5 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright 2016 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 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use target::{Target, TargetResult}; | ||
|
||
pub fn target() -> TargetResult { | ||
let mut base = super::linux_base::opts(); | ||
base.cpu = "v9".to_string(); | ||
base.max_atomic_width = Some(64); | ||
base.exe_allocation_crate = "alloc_system".to_string(); | ||
|
||
Ok(Target { | ||
llvm_target: "sparc64-unknown-linux-gnu".to_string(), | ||
target_endian: "big".to_string(), | ||
target_pointer_width: "64".to_string(), | ||
data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), | ||
arch: "sparc64".to_string(), | ||
target_os: "linux".to_string(), | ||
target_env: "gnu".to_string(), | ||
target_vendor: "unknown".to_string(), | ||
options: base, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright 2016 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 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
use target::{Target, TargetResult}; | ||
|
||
pub fn target() -> TargetResult { | ||
let mut base = super::netbsd_base::opts(); | ||
base.cpu = "v9".to_string(); | ||
base.pre_link_args.push("-m64".to_string()); | ||
base.max_atomic_width = Some(64); | ||
|
||
Ok(Target { | ||
llvm_target: "sparc64-unknown-netbsd".to_string(), | ||
target_endian: "big".to_string(), | ||
target_pointer_width: "64".to_string(), | ||
data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), | ||
arch: "sparc64".to_string(), | ||
target_os: "netbsd".to_string(), | ||
target_env: "".to_string(), | ||
target_vendor: "unknown".to_string(), | ||
options: base, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
// Copyright 2014-2016 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 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// FIXME: This needs an audit for correctness and completeness. | ||
|
||
use llvm::{Integer, Pointer, Float, Double, Struct, Vector, Array}; | ||
use abi::{self, FnType, ArgType}; | ||
use context::CrateContext; | ||
use type_::Type; | ||
|
||
fn ty_size(ty: Type) -> usize { | ||
if ty.kind() == Vector { | ||
bug!("ty_size: unhandled type") | ||
} else { | ||
abi::ty_size(ty, 8) | ||
} | ||
} | ||
|
||
fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> { | ||
fn check_array(ty: Type) -> Option<(Type, u64)> { | ||
let len = ty.array_length() as u64; | ||
if len == 0 { | ||
return None | ||
} | ||
let elt = ty.element_type(); | ||
|
||
// if our element is an HFA/HVA, so are we; multiply members by our len | ||
is_homogenous_aggregate_ty(elt).map(|(base_ty, members)| (base_ty, len * members)) | ||
} | ||
|
||
fn check_struct(ty: Type) -> Option<(Type, u64)> { | ||
let str_tys = ty.field_types(); | ||
if str_tys.len() == 0 { | ||
return None | ||
} | ||
|
||
let mut prev_base_ty = None; | ||
let mut members = 0; | ||
for opt_homog_agg in str_tys.iter().map(|t| is_homogenous_aggregate_ty(*t)) { | ||
match (prev_base_ty, opt_homog_agg) { | ||
// field isn't itself an HFA, so we aren't either | ||
(_, None) => return None, | ||
|
||
// first field - store its type and number of members | ||
(None, Some((field_ty, field_members))) => { | ||
prev_base_ty = Some(field_ty); | ||
members = field_members; | ||
}, | ||
|
||
// 2nd or later field - give up if it's a different type; otherwise incr. members | ||
(Some(prev_ty), Some((field_ty, field_members))) => { | ||
if prev_ty != field_ty { | ||
return None; | ||
} | ||
members += field_members; | ||
} | ||
} | ||
} | ||
|
||
// Because of previous checks, we know prev_base_ty is Some(...) because | ||
// 1. str_tys has at least one element; and | ||
// 2. prev_base_ty was filled in (or we would've returned early) | ||
let (base_ty, members) = (prev_base_ty.unwrap(), members); | ||
|
||
// Ensure there is no padding. | ||
if ty_size(ty) == ty_size(base_ty) * (members as usize) { | ||
Some((base_ty, members)) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
let homog_agg = match ty.kind() { | ||
Float => Some((ty, 1)), | ||
Double => Some((ty, 1)), | ||
Array => check_array(ty), | ||
Struct => check_struct(ty), | ||
_ => None | ||
}; | ||
|
||
// Ensure we have at most eight uniquely addressable members | ||
homog_agg.and_then(|(base_ty, members)| { | ||
if members > 0 && members <= 8 { | ||
Some((base_ty, members)) | ||
} else { | ||
None | ||
} | ||
}) | ||
} | ||
|
||
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) { | ||
if is_reg_ty(ret.ty) { | ||
ret.extend_integer_width_to(64); | ||
return; | ||
} | ||
|
||
// don't return aggregates in registers | ||
ret.make_indirect(ccx); | ||
|
||
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(ret.ty) { | ||
ret.cast = Some(Type::array(&base_ty, members)); | ||
return; | ||
} | ||
let size = ty_size(ret.ty); | ||
if size <= 16 { | ||
let llty = if size <= 1 { | ||
Type::i8(ccx) | ||
} else if size <= 2 { | ||
Type::i16(ccx) | ||
} else if size <= 4 { | ||
Type::i32(ccx) | ||
} else if size <= 8 { | ||
Type::i64(ccx) | ||
} else { | ||
Type::array(&Type::i64(ccx), ((size + 7 ) / 8 ) as u64) | ||
}; | ||
ret.cast = Some(llty); | ||
return; | ||
} | ||
} | ||
|
||
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType) { | ||
if is_reg_ty(arg.ty) { | ||
arg.extend_integer_width_to(64); | ||
return; | ||
} | ||
|
||
if let Some((base_ty, members)) = is_homogenous_aggregate_ty(arg.ty) { | ||
arg.cast = Some(Type::array(&base_ty, members)); | ||
return; | ||
} | ||
|
||
arg.cast = Some(struct_ty(ccx, arg.ty)); | ||
} | ||
|
||
fn is_reg_ty(ty: Type) -> bool { | ||
match ty.kind() { | ||
Integer | ||
| Pointer | ||
| Float | ||
| Double => true, | ||
_ => false | ||
} | ||
} | ||
|
||
fn coerce_to_long(ccx: &CrateContext, size: usize) -> Vec<Type> { | ||
let long_ty = Type::i64(ccx); | ||
let mut args = Vec::new(); | ||
|
||
let mut n = size / 64; | ||
while n > 0 { | ||
args.push(long_ty); | ||
n -= 1; | ||
} | ||
|
||
let r = size % 64; | ||
if r > 0 { | ||
args.push(Type::ix(ccx, r as u64)); | ||
} | ||
|
||
args | ||
} | ||
|
||
fn struct_ty(ccx: &CrateContext, ty: Type) -> Type { | ||
let size = ty_size(ty) * 8; | ||
Type::struct_(ccx, &coerce_to_long(ccx, size), false) | ||
} | ||
|
||
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) { | ||
if !fty.ret.is_ignore() { | ||
classify_ret_ty(ccx, &mut fty.ret); | ||
} | ||
|
||
for arg in &mut fty.args { | ||
if arg.is_ignore() { continue; } | ||
classify_arg_ty(ccx, arg); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.