mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-21 03:14:11 +00:00
auto merge of #20980 : richo/rust/final-power, r=alexcrichton
Originally, this was going to be discussed and revisted, however I've been working on this for months, and a rebase on top of master was about 1 flight's worth of work so I just went ahead and did it. This gets you as far as being able to target powerpc with, eg: LD_LIBRARY_PATH=./x86_64-unknown-linux-gnu/stage2/lib/ x86_64-unknown-linux-gnu/stage2/bin/rustc -C linker=powerpc-linux-gnu-gcc --target powerpc-unknown-linux-gnu hello.rs Would really love to get this out before 1.0. r? @alexcrichton
This commit is contained in:
commit
0c96037ec1
8
configure
vendored
8
configure
vendored
@ -448,6 +448,10 @@ case $CFG_CPUTYPE in
|
||||
CFG_CPUTYPE=aarch64
|
||||
;;
|
||||
|
||||
powerpc)
|
||||
CFG_CPUTYPE=powerpc
|
||||
;;
|
||||
|
||||
x86_64 | x86-64 | x64 | amd64)
|
||||
CFG_CPUTYPE=x86_64
|
||||
;;
|
||||
@ -1004,7 +1008,7 @@ do
|
||||
make_dir $t/rt/jemalloc
|
||||
for i in \
|
||||
isaac sync test \
|
||||
arch/i386 arch/x86_64 arch/arm arch/aarch64 arch/mips
|
||||
arch/i386 arch/x86_64 arch/arm arch/aarch64 arch/mips arch/powerpc
|
||||
do
|
||||
make_dir $t/rt/stage$s/$i
|
||||
done
|
||||
@ -1169,7 +1173,7 @@ do
|
||||
|
||||
msg "configuring LLVM for $gnu_t"
|
||||
|
||||
LLVM_TARGETS="--enable-targets=x86,x86_64,arm,aarch64,mips"
|
||||
LLVM_TARGETS="--enable-targets=x86,x86_64,arm,aarch64,mips,powerpc"
|
||||
LLVM_BUILD="--build=$gnu_t"
|
||||
LLVM_HOST="--host=$gnu_t"
|
||||
LLVM_TARGET="--target=$gnu_t"
|
||||
|
28
mk/cfg/powerpc-unknown-linux-gnu.mk
Normal file
28
mk/cfg/powerpc-unknown-linux-gnu.mk
Normal file
@ -0,0 +1,28 @@
|
||||
# powerpc-unknown-linux-gnu configuration
|
||||
CROSS_PREFIX_powerpc-unknown-linux-gnu=powerpc-linux-gnu-
|
||||
CC_powerpc-unknown-linux-gnu=$(CC)
|
||||
CXX_powerpc-unknown-linux-gnu=$(CXX)
|
||||
CPP_powerpc-unknown-linux-gnu=$(CPP)
|
||||
AR_powerpc-unknown-linux-gnu=$(AR)
|
||||
CFG_LIB_NAME_powerpc-unknown-linux-gnu=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_powerpc-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_powerpc-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_powerpc-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_powerpc-unknown-linux-gnu := -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_powerpc-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_powerpc-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_powerpc-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_powerpc-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_powerpc-unknown-linux-gnu := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_powerpc-unknown-linux-gnu := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_powerpc-unknown-linux-gnu := .linux.def
|
||||
CFG_LLC_FLAGS_powerpc-unknown-linux-gnu :=
|
||||
CFG_INSTALL_NAME_powerpc-unknown-linux-gnu =
|
||||
CFG_EXE_SUFFIX_powerpc-unknown-linux-gnu =
|
||||
CFG_WINDOWSY_powerpc-unknown-linux-gnu :=
|
||||
CFG_UNIXY_powerpc-unknown-linux-gnu := 1
|
||||
CFG_PATH_MUNGE_powerpc-unknown-linux-gnu := true
|
||||
CFG_LDPATH_powerpc-unknown-linux-gnu :=
|
||||
CFG_RUN_powerpc-unknown-linux-gnu=$(2)
|
||||
CFG_RUN_TARG_powerpc-unknown-linux-gnu=$(call CFG_RUN_powerpc-unknown-linux-gnu,,$(2))
|
||||
CFG_GNU_TRIPLE_powerpc-unknown-linux-gnu := powerpc-unknown-linux-gnu
|
@ -263,7 +263,7 @@ endif
|
||||
######################################################################
|
||||
|
||||
# FIXME: x86-ism
|
||||
LLVM_COMPONENTS=x86 arm aarch64 mips ipo bitreader bitwriter linker asmparser mcjit \
|
||||
LLVM_COMPONENTS=x86 arm aarch64 mips powerpc ipo bitreader bitwriter linker asmparser mcjit \
|
||||
interpreter instrumentation
|
||||
|
||||
# Only build these LLVM tools
|
||||
|
@ -177,7 +177,7 @@ define CFG_MAKE_TOOLCHAIN
|
||||
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
|
||||
$$(call CFG_INSTALL_NAME_$(1),$$(4))
|
||||
|
||||
ifeq ($$(findstring $(HOST_$(1)),arm aarch64 mips mipsel),)
|
||||
ifeq ($$(findstring $(HOST_$(1)),arm aarch64 mips mipsel powerpc),)
|
||||
|
||||
# We're using llvm-mc as our assembler because it supports
|
||||
# .cfi pseudo-ops on mac
|
||||
@ -189,7 +189,7 @@ define CFG_MAKE_TOOLCHAIN
|
||||
-o=$$(1)
|
||||
else
|
||||
|
||||
# For the ARM, AARCH64 and MIPS crosses, use the toolchain assembler
|
||||
# For the ARM, AARCH64, MIPS and POWER crosses, use the toolchain assembler
|
||||
# FIXME: We should be able to use the LLVM assembler
|
||||
CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
|
||||
$$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
|
||||
|
@ -2170,7 +2170,7 @@ arbitrarily complex configurations through nesting.
|
||||
The following configurations must be defined by the implementation:
|
||||
|
||||
* `target_arch = "..."`. Target CPU architecture, such as `"x86"`, `"x86_64"`
|
||||
`"mips"`, `"arm"`, or `"aarch64"`.
|
||||
`"mips"`, `"powerpc"`, `"arm"`, or `"aarch64"`.
|
||||
* `target_endian = "..."`. Endianness of the target CPU, either `"little"` or
|
||||
`"big"`.
|
||||
* `target_family = "..."`. Operating system family of the target, e. g.
|
||||
|
@ -119,7 +119,8 @@ unsafe fn exchange_free(ptr: *mut u8, old_size: uint, align: uint) {
|
||||
not(feature = "external_crate"),
|
||||
any(target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel")))]
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc")))]
|
||||
const MIN_ALIGN: uint = 8;
|
||||
#[cfg(all(not(feature = "external_funcs"),
|
||||
not(feature = "external_crate"),
|
||||
|
@ -19,18 +19,14 @@ fn size_of_basic() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn size_of_32() {
|
||||
assert_eq!(size_of::<uint>(), 4u);
|
||||
assert_eq!(size_of::<*const uint>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "aarch64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn size_of_64() {
|
||||
assert_eq!(size_of::<uint>(), 8u);
|
||||
assert_eq!(size_of::<*const uint>(), 8u);
|
||||
@ -52,18 +48,14 @@ fn align_of_basic() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn align_of_32() {
|
||||
assert_eq!(align_of::<uint>(), 4u);
|
||||
assert_eq!(align_of::<*const uint>(), 4u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "aarch64"))]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn align_of_64() {
|
||||
assert_eq!(align_of::<uint>(), 8u);
|
||||
assert_eq!(align_of::<*const uint>(), 8u);
|
||||
|
@ -497,7 +497,8 @@ pub mod types {
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
pub mod arch {
|
||||
pub mod c95 {
|
||||
pub type c_char = i8;
|
||||
@ -528,7 +529,8 @@ pub mod types {
|
||||
}
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
pub mod posix88 {
|
||||
pub type off_t = i32;
|
||||
pub type dev_t = u64;
|
||||
@ -642,7 +644,9 @@ pub mod types {
|
||||
pub __size: [u32; 9]
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
|
||||
#[cfg(any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
pub mod posix01 {
|
||||
use types::os::arch::c95::{c_long, c_ulong, time_t};
|
||||
use types::os::arch::posix88::{gid_t, ino_t};
|
||||
@ -2697,7 +2701,9 @@ pub mod consts {
|
||||
pub const EHWPOISON: c_int = 133;
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
|
||||
#[cfg(any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
pub mod posix88 {
|
||||
use types::os::arch::c95::c_int;
|
||||
use types::common::c95::c_void;
|
||||
@ -2982,7 +2988,8 @@ pub mod consts {
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "aarch64")))]
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc")))]
|
||||
pub const PTHREAD_STACK_MIN: size_t = 131072;
|
||||
|
||||
pub const CLOCK_REALTIME: c_int = 0;
|
||||
@ -3040,7 +3047,9 @@ pub mod consts {
|
||||
pub const SHUT_WR: c_int = 1;
|
||||
pub const SHUT_RDWR: c_int = 2;
|
||||
}
|
||||
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
|
||||
#[cfg(any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
pub mod bsd44 {
|
||||
use types::os::arch::c95::c_int;
|
||||
|
||||
@ -3115,7 +3124,9 @@ pub mod consts {
|
||||
pub const MAP_NONBLOCK : c_int = 0x010000;
|
||||
pub const MAP_STACK : c_int = 0x020000;
|
||||
}
|
||||
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
|
||||
#[cfg(any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
pub mod extra {
|
||||
use types::os::arch::c95::c_int;
|
||||
|
||||
|
@ -72,6 +72,7 @@ mod i686_unknown_dragonfly;
|
||||
mod i686_unknown_linux_gnu;
|
||||
mod mips_unknown_linux_gnu;
|
||||
mod mipsel_unknown_linux_gnu;
|
||||
mod powerpc_unknown_linux_gnu;
|
||||
mod x86_64_apple_darwin;
|
||||
mod x86_64_apple_ios;
|
||||
mod x86_64_pc_windows_gnu;
|
||||
@ -95,7 +96,7 @@ pub struct Target {
|
||||
/// OS name to use for conditional compilation.
|
||||
pub target_os: String,
|
||||
/// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm",
|
||||
/// "aarch64", and "mips". "mips" includes "mipsel".
|
||||
/// "aarch64", "mips", and "powerpc". "mips" includes "mipsel".
|
||||
pub arch: String,
|
||||
/// Optional settings with defaults.
|
||||
pub options: TargetOptions,
|
||||
@ -339,6 +340,7 @@ impl Target {
|
||||
i686_unknown_linux_gnu,
|
||||
mips_unknown_linux_gnu,
|
||||
mipsel_unknown_linux_gnu,
|
||||
powerpc_unknown_linux_gnu,
|
||||
arm_linux_androideabi,
|
||||
arm_unknown_linux_gnueabi,
|
||||
arm_unknown_linux_gnueabihf,
|
||||
|
26
src/librustc_back/target/powerpc_unknown_linux_gnu.rs
Normal file
26
src/librustc_back/target/powerpc_unknown_linux_gnu.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2012 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;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::linux_base::opts();
|
||||
base.pre_link_args.push("-m32".to_string());
|
||||
|
||||
Target {
|
||||
data_layout: "E-S8-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string(),
|
||||
llvm_target: "powerpc-unknown-linux-gnu".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
target_pointer_width: "32".to_string(),
|
||||
arch: "powerpc".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
options: base,
|
||||
}
|
||||
}
|
@ -1974,6 +1974,11 @@ extern {
|
||||
pub fn LLVMInitializeMipsTargetMC();
|
||||
pub fn LLVMInitializeMipsAsmPrinter();
|
||||
pub fn LLVMInitializeMipsAsmParser();
|
||||
pub fn LLVMInitializePowerPCTargetInfo();
|
||||
pub fn LLVMInitializePowerPCTarget();
|
||||
pub fn LLVMInitializePowerPCTargetMC();
|
||||
pub fn LLVMInitializePowerPCAsmPrinter();
|
||||
pub fn LLVMInitializePowerPCAsmParser();
|
||||
|
||||
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
|
||||
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
|
||||
@ -2249,6 +2254,12 @@ pub unsafe fn static_link_hack_this_sucks() {
|
||||
LLVMInitializeMipsAsmPrinter();
|
||||
LLVMInitializeMipsAsmParser();
|
||||
|
||||
LLVMInitializePowerPCTargetInfo();
|
||||
LLVMInitializePowerPCTarget();
|
||||
LLVMInitializePowerPCTargetMC();
|
||||
LLVMInitializePowerPCAsmPrinter();
|
||||
LLVMInitializePowerPCAsmParser();
|
||||
|
||||
LLVMRustSetLLVMOptions(0 as c_int,
|
||||
0 as *const _);
|
||||
|
||||
|
@ -1039,6 +1039,12 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||
llvm::LLVMInitializeMipsAsmPrinter();
|
||||
llvm::LLVMInitializeMipsAsmParser();
|
||||
|
||||
llvm::LLVMInitializePowerPCTargetInfo();
|
||||
llvm::LLVMInitializePowerPCTarget();
|
||||
llvm::LLVMInitializePowerPCTargetMC();
|
||||
llvm::LLVMInitializePowerPCAsmPrinter();
|
||||
llvm::LLVMInitializePowerPCAsmParser();
|
||||
|
||||
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
|
||||
llvm_args.as_ptr());
|
||||
});
|
||||
|
@ -161,10 +161,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
||||
// Default per-arch clobbers
|
||||
// Basically what clang does
|
||||
|
||||
#[cfg(any(target_arch = "arm",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
fn get_clobbers() -> String {
|
||||
"".to_string()
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use trans::cabi_x86_64;
|
||||
use trans::cabi_x86_win64;
|
||||
use trans::cabi_arm;
|
||||
use trans::cabi_aarch64;
|
||||
use trans::cabi_powerpc;
|
||||
use trans::cabi_mips;
|
||||
use trans::type_::Type;
|
||||
|
||||
@ -125,6 +126,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
|
||||
cabi_arm::compute_abi_info(ccx, atys, rty, ret_def, flavor)
|
||||
},
|
||||
"mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
"powerpc" => cabi_powerpc::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)
|
||||
[]),
|
||||
}
|
||||
|
183
src/librustc_trans/trans/cabi_powerpc.rs
Normal file
183
src/librustc_trans/trans/cabi_powerpc.rs
Normal file
@ -0,0 +1,183 @@
|
||||
// Copyright 2014-2015 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 libc::c_uint;
|
||||
use llvm;
|
||||
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
|
||||
use llvm::{StructRetAttribute, ZExtAttribute};
|
||||
use trans::cabi::{FnType, ArgType};
|
||||
use trans::context::CrateContext;
|
||||
use trans::type_::Type;
|
||||
|
||||
use std::cmp;
|
||||
|
||||
fn align_up_to(off: uint, a: uint) -> uint {
|
||||
return (off + a - 1u) / a * a;
|
||||
}
|
||||
|
||||
fn align(off: uint, ty: Type) -> uint {
|
||||
let a = ty_align(ty);
|
||||
return align_up_to(off, a);
|
||||
}
|
||||
|
||||
fn ty_align(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
1
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let elt = ty.element_type();
|
||||
ty_align(elt)
|
||||
}
|
||||
_ => panic!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_size(ty: Type) -> uint {
|
||||
match ty.kind() {
|
||||
Integer => {
|
||||
unsafe {
|
||||
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
|
||||
}
|
||||
}
|
||||
Pointer => 4,
|
||||
Float => 4,
|
||||
Double => 8,
|
||||
Struct => {
|
||||
if ty.is_packed() {
|
||||
let str_tys = ty.field_types();
|
||||
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
|
||||
} else {
|
||||
let str_tys = ty.field_types();
|
||||
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
|
||||
align(size, ty)
|
||||
}
|
||||
}
|
||||
Array => {
|
||||
let len = ty.array_length();
|
||||
let elt = ty.element_type();
|
||||
let eltsz = ty_size(elt);
|
||||
len * eltsz
|
||||
}
|
||||
_ => panic!("ty_size: unhandled type")
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
|
||||
if is_reg_ty(ty) {
|
||||
let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
|
||||
ArgType::direct(ty, None, None, attr)
|
||||
} else {
|
||||
ArgType::indirect(ty, Some(StructRetAttribute))
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType {
|
||||
let orig_offset = *offset;
|
||||
let size = ty_size(ty) * 8;
|
||||
let mut align = ty_align(ty);
|
||||
|
||||
align = cmp::min(cmp::max(align, 4), 8);
|
||||
*offset = align_up_to(*offset, align);
|
||||
*offset += align_up_to(size, align * 8) / 8;
|
||||
|
||||
if is_reg_ty(ty) {
|
||||
let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
|
||||
ArgType::direct(ty, None, None, attr)
|
||||
} else {
|
||||
ArgType::direct(
|
||||
ty,
|
||||
Some(struct_ty(ccx, ty)),
|
||||
padding_ty(ccx, align, orig_offset),
|
||||
None
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_reg_ty(ty: Type) -> bool {
|
||||
return match ty.kind() {
|
||||
Integer
|
||||
| Pointer
|
||||
| Float
|
||||
| Double => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
fn padding_ty(ccx: &CrateContext, align: uint, offset: uint) -> Option<Type> {
|
||||
if ((align - 1 ) & offset) > 0 {
|
||||
Some(Type::i32(ccx))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn coerce_to_int(ccx: &CrateContext, size: uint) -> Vec<Type> {
|
||||
let int_ty = Type::i32(ccx);
|
||||
let mut args = Vec::new();
|
||||
|
||||
let mut n = size / 32;
|
||||
while n > 0 {
|
||||
args.push(int_ty);
|
||||
n -= 1;
|
||||
}
|
||||
|
||||
let r = size % 32;
|
||||
if r > 0 {
|
||||
unsafe {
|
||||
args.push(Type::from_ref(llvm::LLVMIntTypeInContext(ccx.llcx(), r as c_uint)));
|
||||
}
|
||||
}
|
||||
|
||||
args
|
||||
}
|
||||
|
||||
fn struct_ty(ccx: &CrateContext, ty: Type) -> Type {
|
||||
let size = ty_size(ty) * 8;
|
||||
Type::struct_(ccx, coerce_to_int(ccx, size).as_slice(), false)
|
||||
}
|
||||
|
||||
pub fn compute_abi_info(ccx: &CrateContext,
|
||||
atys: &[Type],
|
||||
rty: Type,
|
||||
ret_def: bool) -> FnType {
|
||||
let ret_ty = if ret_def {
|
||||
classify_ret_ty(ccx, rty)
|
||||
} else {
|
||||
ArgType::direct(Type::void(ccx), None, None, None)
|
||||
};
|
||||
|
||||
let sret = ret_ty.is_indirect();
|
||||
let mut arg_tys = Vec::new();
|
||||
let mut offset = if sret { 4 } else { 0 };
|
||||
|
||||
for aty in atys.iter() {
|
||||
let ty = classify_arg_ty(ccx, *aty, &mut offset);
|
||||
arg_tys.push(ty);
|
||||
};
|
||||
|
||||
return FnType {
|
||||
arg_tys: arg_tys,
|
||||
ret_ty: ret_ty,
|
||||
};
|
||||
}
|
@ -45,6 +45,7 @@ mod cabi_x86_win64;
|
||||
mod cabi_arm;
|
||||
mod cabi_aarch64;
|
||||
mod cabi_mips;
|
||||
mod cabi_powerpc;
|
||||
mod foreign;
|
||||
mod intrinsic;
|
||||
mod debuginfo;
|
||||
|
@ -1422,6 +1422,11 @@ mod arch_consts {
|
||||
pub const ARCH: &'static str = "mipsel";
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
mod arch_consts {
|
||||
pub const ARCH: &'static str = "powerpc";
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::v1::*;
|
||||
|
@ -32,7 +32,8 @@ mod imp {
|
||||
any(target_arch = "x86_64",
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64")))]
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc")))]
|
||||
fn getrandom(buf: &mut [u8]) -> libc::c_long {
|
||||
extern "C" {
|
||||
fn syscall(number: libc::c_long, ...) -> libc::c_long;
|
||||
@ -44,6 +45,8 @@ mod imp {
|
||||
const NR_GETRANDOM: libc::c_long = 355;
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
const NR_GETRANDOM: libc::c_long = 384;
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
const NR_GETRANDOM: libc::c_long = 384;
|
||||
|
||||
unsafe {
|
||||
syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0u)
|
||||
@ -54,7 +57,8 @@ mod imp {
|
||||
any(target_arch = "x86_64",
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64"))))]
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc"))))]
|
||||
fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }
|
||||
|
||||
fn getrandom_fill_bytes(v: &mut [u8]) {
|
||||
@ -91,7 +95,8 @@ mod imp {
|
||||
any(target_arch = "x86_64",
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64")))]
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc")))]
|
||||
fn is_getrandom_available() -> bool {
|
||||
use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
|
||||
|
||||
@ -119,7 +124,8 @@ mod imp {
|
||||
any(target_arch = "x86_64",
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64"))))]
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc"))))]
|
||||
fn is_getrandom_available() -> bool { false }
|
||||
|
||||
/// A random number generator that retrieves randomness straight from
|
||||
|
@ -81,6 +81,9 @@ pub const unwinder_private_data_size: uint = 2;
|
||||
#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
|
||||
pub const unwinder_private_data_size: uint = 2;
|
||||
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
pub const unwinder_private_data_size: uint = 2;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct _Unwind_Exception {
|
||||
pub exception_class: _Unwind_Exception_Class,
|
||||
|
@ -231,6 +231,12 @@ pub unsafe fn record_sp_limit(limit: uint) {
|
||||
unsafe fn target_record_sp_limit(_: uint) {
|
||||
}
|
||||
|
||||
// powerpc - FIXME(POWERPC): missing...
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
unsafe fn target_record_sp_limit(_: uint) {
|
||||
}
|
||||
|
||||
|
||||
// iOS segmented stack is disabled for now, see related notes
|
||||
#[cfg(all(target_arch = "arm", target_os = "ios"))] #[inline(always)]
|
||||
unsafe fn target_record_sp_limit(_: uint) {
|
||||
@ -326,6 +332,12 @@ pub unsafe fn get_sp_limit() -> uint {
|
||||
1024
|
||||
}
|
||||
|
||||
// powepc - FIXME(POWERPC): missing...
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
unsafe fn target_get_sp_limit() -> uint {
|
||||
1024
|
||||
}
|
||||
|
||||
// iOS doesn't support segmented stacks yet. This function might
|
||||
// be called by runtime though so it is unsafe to mark it as
|
||||
// unreachable, let's return a fixed constant.
|
||||
|
@ -33,7 +33,9 @@ pub const FIONBIO: libc::c_ulong = 0x8004667e;
|
||||
target_os = "android"))]
|
||||
pub const FIONBIO: libc::c_ulong = 0x5421;
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips", target_arch = "mipsel")))]
|
||||
any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc")))]
|
||||
pub const FIONBIO: libc::c_ulong = 0x667e;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
@ -49,7 +51,9 @@ pub const FIOCLEX: libc::c_ulong = 0x20006601;
|
||||
target_os = "android"))]
|
||||
pub const FIOCLEX: libc::c_ulong = 0x5451;
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips", target_arch = "mipsel")))]
|
||||
any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc")))]
|
||||
pub const FIOCLEX: libc::c_ulong = 0x6601;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
@ -182,7 +186,9 @@ mod signal {
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips", target_arch = "mipsel")))]
|
||||
any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc")))]
|
||||
mod signal {
|
||||
use libc;
|
||||
|
||||
|
@ -150,6 +150,7 @@ mod imp {
|
||||
all(target_os = "linux", target_arch = "aarch64"),
|
||||
all(target_os = "linux", target_arch = "mips"), // may not match
|
||||
all(target_os = "linux", target_arch = "mipsel"), // may not match
|
||||
all(target_os = "linux", target_arch = "powerpc"), // may not match
|
||||
target_os = "android"))] // may not match
|
||||
mod signal {
|
||||
use libc;
|
||||
|
@ -126,7 +126,8 @@ mod os {
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: uint = 48 - 8;
|
||||
@ -136,7 +137,8 @@ mod os {
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
@ -146,7 +148,8 @@ mod os {
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
const __SIZEOF_PTHREAD_RWLOCK_T: uint = 32 - 8;
|
||||
|
||||
#[repr(C)]
|
||||
|
18
src/rt/arch/powerpc/morestack.S
Normal file
18
src/rt/arch/powerpc/morestack.S
Normal file
@ -0,0 +1,18 @@
|
||||
// Mark stack as non-executable
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack, "", %progbits
|
||||
#endif
|
||||
|
||||
/* See i386/morestack.S for the lengthy, general explanation. */
|
||||
|
||||
.global rust_stack_exhausted
|
||||
|
||||
.hidden __morestack
|
||||
|
||||
// FIXME(POWERPC): this might not be perfectly right but works for now
|
||||
__morestack:
|
||||
.cfi_startproc
|
||||
bl rust_stack_exhausted
|
||||
// the above function ensures that it never returns
|
||||
.cfi_endproc
|
||||
.end __morestack
|
4
src/rt/arch/powerpc/record_sp.S
Normal file
4
src/rt/arch/powerpc/record_sp.S
Normal file
@ -0,0 +1,4 @@
|
||||
// Mark stack as non-executable
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack, "", %progbits
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
# If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
|
||||
# The actual contents of this file do not matter, but to trigger a change on the
|
||||
# build bots then the contents should be changed so git updates the mtime.
|
||||
2015-01-05
|
||||
2015-01-13
|
||||
|
Loading…
Reference in New Issue
Block a user