Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add mips64-gnu and mips64el-gnu targets #36024

Merged
merged 6 commits into from
Sep 2, 2016
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mk/cfg/mips64-unknown-linux-gnuabi64.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# rustbuild-only target
1 change: 1 addition & 0 deletions mk/cfg/mips64el-unknown-linux-gnuabi64.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# rustbuild-only target
3 changes: 2 additions & 1 deletion src/liballoc_jemalloc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64")))]
target_arch = "powerpc64",
target_arch = "mips64")))]
const MIN_ALIGN: usize = 16;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure if these MIN_ALIGN values make sense for the mips64.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// MALLOCX_ALIGN(a) macro
Expand Down
3 changes: 2 additions & 1 deletion src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
target_arch = "asmjs")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
target_arch = "aarch64")))]
target_arch = "aarch64",
target_arch = "mips64")))]
const MIN_ALIGN: usize = 16;

#[no_mangle]
Expand Down
2 changes: 1 addition & 1 deletion src/libpanic_unwind/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // RAX, RDX
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1

#[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
#[cfg(any(target_arch = "mips", target_arch = "mipsel", target_arch = "mips64"))]
const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1

#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
Expand Down
31 changes: 31 additions & 0 deletions src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
Ok(Target {
llvm_target: "mips64-unknown-linux-gnuabi64".to_string(),
target_endian: "big".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
options: TargetOptions {
// NOTE(mips64r2) matches C toolchain
cpu: "mips64r2".to_string(),
features: "+mips64r2".to_string(),
max_atomic_width: 64,
..super::linux_base::opts()
},
})
}
31 changes: 31 additions & 0 deletions src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
Ok(Target {
llvm_target: "mips64el-unknown-linux-gnuabi64".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
options: TargetOptions {
// NOTE(mips64r2) matches C toolchain
cpu: "mips64r2".to_string(),
features: "+mips64r2".to_string(),
max_atomic_width: 64,
..super::linux_base::opts()
},
})
}
2 changes: 2 additions & 0 deletions src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ supported_targets! {
("i686-unknown-linux-gnu", i686_unknown_linux_gnu),
("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu),
("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu),
("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use cabi_aarch64;
use cabi_powerpc;
use cabi_powerpc64;
use cabi_mips;
use cabi_mips64;
use cabi_asmjs;
use machine::{llalign_of_min, llsize_of, llsize_of_real, llsize_of_store};
use type_::Type;
Expand Down Expand Up @@ -498,6 +499,7 @@ impl FnType {
cabi_arm::compute_abi_info(ccx, self, flavor);
},
"mips" => cabi_mips::compute_abi_info(ccx, self),
"mips64" => cabi_mips64::compute_abi_info(ccx, self),
"powerpc" => cabi_powerpc::compute_abi_info(ccx, self),
"powerpc64" => cabi_powerpc64::compute_abi_info(ccx, self),
"asmjs" => cabi_asmjs::compute_abi_info(ccx, self),
Expand Down
168 changes: 168 additions & 0 deletions src/librustc_trans/cabi_mips64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// 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.

#![allow(non_upper_case_globals)]

use libc::c_uint;
use std::cmp;
use llvm;
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
use abi::{ArgType, FnType};
use context::CrateContext;
use type_::Type;

fn align_up_to(off: usize, a: usize) -> usize {
return (off + a - 1) / a * a;
}

fn align(off: usize, ty: Type) -> usize {
let a = ty_align(ty);
return align_up_to(off, a);
}

fn ty_align(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 8,
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)
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
ty_align(elt) * len
}
_ => bug!("ty_align: unhandled type")
}
}

fn ty_size(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 8,
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
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
_ => bug!("ty_size: unhandled type")
}
}

fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
if is_reg_ty(ret.ty) {
ret.extend_integer_width_to(64);
} else {
ret.make_indirect(ccx);
}
}

fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut usize) {
let orig_offset = *offset;
let size = ty_size(arg.ty) * 8;
let mut align = ty_align(arg.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(arg.ty) {
arg.cast = Some(struct_ty(ccx, arg.ty));
arg.pad = padding_ty(ccx, align, orig_offset);
} else {
arg.extend_integer_width_to(64);
}
}

fn is_reg_ty(ty: Type) -> bool {
return match ty.kind() {
Integer
| Pointer
| Float
| Double
| Vector => true,
_ => false
};
}

fn padding_ty(ccx: &CrateContext, align: usize, offset: usize) -> Option<Type> {
if ((align - 1 ) & offset) > 0 {
Some(Type::i32(ccx))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be incorrect, especially if only 64-bit registers are in use.

} else {
None
}
}

fn coerce_to_int(ccx: &CrateContext, size: usize) -> Vec<Type> {
let int_ty = Type::i32(ccx);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

let mut args = Vec::new();

let mut n = size / 64;
while n > 0 {
args.push(int_ty);
n -= 1;
}

let r = size % 64;
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), false)
}

pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
if !fty.ret.is_ignore() {
classify_ret_ty(ccx, &mut fty.ret);
}

let mut offset = if fty.ret.is_indirect() { 8 } else { 0 };
for arg in &mut fty.args {
if arg.is_ignore() { continue; }
classify_arg_ty(ccx, arg, &mut offset);
}
}
12 changes: 2 additions & 10 deletions src/librustc_trans/cabi_powerpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ fn align(off: usize, ty: Type) -> usize {

fn ty_align(ty: Type) -> usize {
match ty.kind() {
Integer => {
unsafe {
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as usize) + 7) / 8
}
}
Integer => ((ty.int_width() as usize) + 7) / 8,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to mention but these two are drive by cleanups. The int_width method is equivalent to the llvm call that was deleted.

Pointer => 4,
Float => 4,
Double => 8,
Expand All @@ -54,11 +50,7 @@ fn ty_align(ty: Type) -> usize {

fn ty_size(ty: Type) -> usize {
match ty.kind() {
Integer => {
unsafe {
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as usize) + 7) / 8
}
}
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 4,
Float => 4,
Double => 8,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ mod cabi_aarch64;
mod cabi_arm;
mod cabi_asmjs;
mod cabi_mips;
mod cabi_mips64;
mod cabi_powerpc;
mod cabi_powerpc64;
mod cabi_x86;
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ pub mod consts {
/// - arm
/// - aarch64
/// - mips
/// - mips64
/// - powerpc
/// - powerpc64
#[stable(feature = "env", since = "1.0.0")]
Expand Down Expand Up @@ -928,6 +929,11 @@ mod arch {
pub const ARCH: &'static str = "mips";
}

#[cfg(target_arch = "mips64")]
mod arch {
pub const ARCH: &'static str = "mips64";
}

#[cfg(target_arch = "powerpc")]
mod arch {
pub const ARCH: &'static str = "powerpc";
Expand Down
5 changes: 5 additions & 0 deletions src/libstd/os/linux/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ mod arch {
}
}

#[cfg(target_arch = "mips64")]
mod arch {
pub use libc::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I need to add stability attributes. This whole module is deprecated anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually ok to just leave this out, the deprecated modules are just here for backwards compatibility. MIPS64 didn't even work back then, so there's no compatibility to be had!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I cfg(target_arch = "mips64") away all these deprecated bits then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, nah this is fine to just keep everything else compiling.

}

#[cfg(target_arch = "aarch64")]
mod arch {
use os::raw::{c_long, c_int};
Expand Down
3 changes: 3 additions & 0 deletions src/libunwind/libunwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ pub const unwinder_private_data_size: usize = 2;
#[cfg(target_arch = "mips")]
pub const unwinder_private_data_size: usize = 2;

#[cfg(target_arch = "mips64")]
pub const unwinder_private_data_size: usize = 2;

#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
pub const unwinder_private_data_size: usize = 2;

Expand Down