Skip to content

Commit 689c6c4

Browse files
authored
Auto merge of rust-lang#36024 - japaric:mips64, r=alexcrichton
add mips64-gnu and mips64el-gnu targets With this commit one can build no_core (and probably no_std as well) Rust programs for these targets. It's not yet possible to cross compile std for these targets because rust-lang/libc doesn't know about the mips64 architecture. These targets have been tested by cross compiling the "smallest hello" program (see code below) and then running it under QEMU. ``` rust extern { fn puts(_: *const u8); } fn start(_: isize, _: *const *const u8) -> isize { unsafe { let msg = b"Hello, world!\0"; puts(msg as *const _ as *const u8); } 0 } trait Copy {} trait Sized {} ``` cc rust-lang#36015 r? @alexcrichton cc @brson The cabi stuff is likely wrong. I just copied cabi_mips source and changed some `4`s to `8`s and `32`s to `64`s. It was enough to get libc's `puts` to work but I'd like someone familiar with this module to check it.
2 parents 022cb6d + bbf2c3c commit 689c6c4

File tree

16 files changed

+259
-14
lines changed

16 files changed

+259
-14
lines changed
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# rustbuild-only target
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# rustbuild-only target

src/liballoc_jemalloc/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ const MIN_ALIGN: usize = 8;
7777
#[cfg(all(any(target_arch = "x86",
7878
target_arch = "x86_64",
7979
target_arch = "aarch64",
80-
target_arch = "powerpc64")))]
80+
target_arch = "powerpc64",
81+
target_arch = "mips64")))]
8182
const MIN_ALIGN: usize = 16;
8283

8384
// MALLOCX_ALIGN(a) macro

src/liballoc_system/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
target_arch = "asmjs")))]
3333
const MIN_ALIGN: usize = 8;
3434
#[cfg(all(any(target_arch = "x86_64",
35-
target_arch = "aarch64")))]
35+
target_arch = "aarch64",
36+
target_arch = "mips64")))]
3637
const MIN_ALIGN: usize = 16;
3738

3839
#[no_mangle]

src/liblibc

Submodule liblibc updated 48 files

src/libpanic_unwind/gcc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // RAX, RDX
124124
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
125125
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1
126126

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

130130
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use target::{Target, TargetOptions, TargetResult};
12+
13+
pub fn target() -> TargetResult {
14+
Ok(Target {
15+
llvm_target: "mips64-unknown-linux-gnuabi64".to_string(),
16+
target_endian: "big".to_string(),
17+
target_pointer_width: "64".to_string(),
18+
data_layout: "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
19+
arch: "mips64".to_string(),
20+
target_os: "linux".to_string(),
21+
target_env: "gnu".to_string(),
22+
target_vendor: "unknown".to_string(),
23+
options: TargetOptions {
24+
// NOTE(mips64r2) matches C toolchain
25+
cpu: "mips64r2".to_string(),
26+
features: "+mips64r2".to_string(),
27+
max_atomic_width: 64,
28+
..super::linux_base::opts()
29+
},
30+
})
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use target::{Target, TargetOptions, TargetResult};
12+
13+
pub fn target() -> TargetResult {
14+
Ok(Target {
15+
llvm_target: "mips64el-unknown-linux-gnuabi64".to_string(),
16+
target_endian: "little".to_string(),
17+
target_pointer_width: "64".to_string(),
18+
data_layout: "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
19+
arch: "mips64".to_string(),
20+
target_os: "linux".to_string(),
21+
target_env: "gnu".to_string(),
22+
target_vendor: "unknown".to_string(),
23+
options: TargetOptions {
24+
// NOTE(mips64r2) matches C toolchain
25+
cpu: "mips64r2".to_string(),
26+
features: "+mips64r2".to_string(),
27+
max_atomic_width: 64,
28+
..super::linux_base::opts()
29+
},
30+
})
31+
}

src/librustc_back/target/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ supported_targets! {
128128
("i686-unknown-linux-gnu", i686_unknown_linux_gnu),
129129
("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
130130
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
131+
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
132+
("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
131133
("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu),
132134
("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu),
133135
("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),

src/librustc_trans/abi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use cabi_aarch64;
2121
use cabi_powerpc;
2222
use cabi_powerpc64;
2323
use cabi_mips;
24+
use cabi_mips64;
2425
use cabi_asmjs;
2526
use machine::{llalign_of_min, llsize_of, llsize_of_real, llsize_of_store};
2627
use type_::Type;
@@ -501,6 +502,7 @@ impl FnType {
501502
cabi_arm::compute_abi_info(ccx, self, flavor);
502503
},
503504
"mips" => cabi_mips::compute_abi_info(ccx, self),
505+
"mips64" => cabi_mips64::compute_abi_info(ccx, self),
504506
"powerpc" => cabi_powerpc::compute_abi_info(ccx, self),
505507
"powerpc64" => cabi_powerpc64::compute_abi_info(ccx, self),
506508
"asmjs" => cabi_asmjs::compute_abi_info(ccx, self),

src/librustc_trans/cabi_mips64.rs

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(non_upper_case_globals)]
12+
13+
use libc::c_uint;
14+
use std::cmp;
15+
use llvm;
16+
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
17+
use abi::{ArgType, FnType};
18+
use context::CrateContext;
19+
use type_::Type;
20+
21+
fn align_up_to(off: usize, a: usize) -> usize {
22+
return (off + a - 1) / a * a;
23+
}
24+
25+
fn align(off: usize, ty: Type) -> usize {
26+
let a = ty_align(ty);
27+
return align_up_to(off, a);
28+
}
29+
30+
fn ty_align(ty: Type) -> usize {
31+
match ty.kind() {
32+
Integer => ((ty.int_width() as usize) + 7) / 8,
33+
Pointer => 8,
34+
Float => 4,
35+
Double => 8,
36+
Struct => {
37+
if ty.is_packed() {
38+
1
39+
} else {
40+
let str_tys = ty.field_types();
41+
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
42+
}
43+
}
44+
Array => {
45+
let elt = ty.element_type();
46+
ty_align(elt)
47+
}
48+
Vector => {
49+
let len = ty.vector_length();
50+
let elt = ty.element_type();
51+
ty_align(elt) * len
52+
}
53+
_ => bug!("ty_align: unhandled type")
54+
}
55+
}
56+
57+
fn ty_size(ty: Type) -> usize {
58+
match ty.kind() {
59+
Integer => ((ty.int_width() as usize) + 7) / 8,
60+
Pointer => 8,
61+
Float => 4,
62+
Double => 8,
63+
Struct => {
64+
if ty.is_packed() {
65+
let str_tys = ty.field_types();
66+
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
67+
} else {
68+
let str_tys = ty.field_types();
69+
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
70+
align(size, ty)
71+
}
72+
}
73+
Array => {
74+
let len = ty.array_length();
75+
let elt = ty.element_type();
76+
let eltsz = ty_size(elt);
77+
len * eltsz
78+
}
79+
Vector => {
80+
let len = ty.vector_length();
81+
let elt = ty.element_type();
82+
let eltsz = ty_size(elt);
83+
len * eltsz
84+
}
85+
_ => bug!("ty_size: unhandled type")
86+
}
87+
}
88+
89+
fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
90+
if is_reg_ty(ret.ty) {
91+
ret.extend_integer_width_to(64);
92+
} else {
93+
ret.make_indirect(ccx);
94+
}
95+
}
96+
97+
fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut usize) {
98+
let orig_offset = *offset;
99+
let size = ty_size(arg.ty) * 8;
100+
let mut align = ty_align(arg.ty);
101+
102+
align = cmp::min(cmp::max(align, 4), 8);
103+
*offset = align_up_to(*offset, align);
104+
*offset += align_up_to(size, align * 8) / 8;
105+
106+
if !is_reg_ty(arg.ty) {
107+
arg.cast = Some(struct_ty(ccx, arg.ty));
108+
arg.pad = padding_ty(ccx, align, orig_offset);
109+
} else {
110+
arg.extend_integer_width_to(64);
111+
}
112+
}
113+
114+
fn is_reg_ty(ty: Type) -> bool {
115+
return match ty.kind() {
116+
Integer
117+
| Pointer
118+
| Float
119+
| Double
120+
| Vector => true,
121+
_ => false
122+
};
123+
}
124+
125+
fn padding_ty(ccx: &CrateContext, align: usize, offset: usize) -> Option<Type> {
126+
if ((align - 1 ) & offset) > 0 {
127+
Some(Type::i64(ccx))
128+
} else {
129+
None
130+
}
131+
}
132+
133+
fn coerce_to_int(ccx: &CrateContext, size: usize) -> Vec<Type> {
134+
let int_ty = Type::i64(ccx);
135+
let mut args = Vec::new();
136+
137+
let mut n = size / 64;
138+
while n > 0 {
139+
args.push(int_ty);
140+
n -= 1;
141+
}
142+
143+
let r = size % 64;
144+
if r > 0 {
145+
unsafe {
146+
args.push(Type::from_ref(llvm::LLVMIntTypeInContext(ccx.llcx(), r as c_uint)));
147+
}
148+
}
149+
150+
args
151+
}
152+
153+
fn struct_ty(ccx: &CrateContext, ty: Type) -> Type {
154+
let size = ty_size(ty) * 8;
155+
Type::struct_(ccx, &coerce_to_int(ccx, size), false)
156+
}
157+
158+
pub fn compute_abi_info(ccx: &CrateContext, fty: &mut FnType) {
159+
if !fty.ret.is_ignore() {
160+
classify_ret_ty(ccx, &mut fty.ret);
161+
}
162+
163+
let mut offset = if fty.ret.is_indirect() { 8 } else { 0 };
164+
for arg in &mut fty.args {
165+
if arg.is_ignore() { continue; }
166+
classify_arg_ty(ccx, arg, &mut offset);
167+
}
168+
}

src/librustc_trans/cabi_powerpc.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,7 @@ fn align(off: usize, ty: Type) -> usize {
2828

2929
fn ty_align(ty: Type) -> usize {
3030
match ty.kind() {
31-
Integer => {
32-
unsafe {
33-
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as usize) + 7) / 8
34-
}
35-
}
31+
Integer => ((ty.int_width() as usize) + 7) / 8,
3632
Pointer => 4,
3733
Float => 4,
3834
Double => 8,
@@ -54,11 +50,7 @@ fn ty_align(ty: Type) -> usize {
5450

5551
fn ty_size(ty: Type) -> usize {
5652
match ty.kind() {
57-
Integer => {
58-
unsafe {
59-
((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as usize) + 7) / 8
60-
}
61-
}
53+
Integer => ((ty.int_width() as usize) + 7) / 8,
6254
Pointer => 4,
6355
Float => 4,
6456
Double => 8,

src/librustc_trans/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ mod cabi_aarch64;
9898
mod cabi_arm;
9999
mod cabi_asmjs;
100100
mod cabi_mips;
101+
mod cabi_mips64;
101102
mod cabi_powerpc;
102103
mod cabi_powerpc64;
103104
mod cabi_x86;

src/libstd/env.rs

+6
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ pub mod consts {
659659
/// - arm
660660
/// - aarch64
661661
/// - mips
662+
/// - mips64
662663
/// - powerpc
663664
/// - powerpc64
664665
#[stable(feature = "env", since = "1.0.0")]
@@ -926,6 +927,11 @@ mod arch {
926927
pub const ARCH: &'static str = "mips";
927928
}
928929

930+
#[cfg(target_arch = "mips64")]
931+
mod arch {
932+
pub const ARCH: &'static str = "mips64";
933+
}
934+
929935
#[cfg(target_arch = "powerpc")]
930936
mod arch {
931937
pub const ARCH: &'static str = "powerpc";

src/libstd/os/linux/raw.rs

+5
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ mod arch {
155155
}
156156
}
157157

158+
#[cfg(target_arch = "mips64")]
159+
mod arch {
160+
pub use libc::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
161+
}
162+
158163
#[cfg(target_arch = "aarch64")]
159164
mod arch {
160165
use os::raw::{c_long, c_int};

src/libunwind/libunwind.rs

+3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ pub const unwinder_private_data_size: usize = 2;
5656
#[cfg(target_arch = "mips")]
5757
pub const unwinder_private_data_size: usize = 2;
5858

59+
#[cfg(target_arch = "mips64")]
60+
pub const unwinder_private_data_size: usize = 2;
61+
5962
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
6063
pub const unwinder_private_data_size: usize = 2;
6164

0 commit comments

Comments
 (0)