about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/librustc_llvm/build.rs3
-rw-r--r--src/librustc_llvm/lib.rs6
-rw-r--r--src/librustc_trans/abi.rs2
-rw-r--r--src/librustc_trans/cabi_sparc.rs108
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/rustllvm/llvm-auto-clean-trigger2
7 files changed, 121 insertions, 3 deletions
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 6ba6b8e6c86..09dbd9f8220 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -81,7 +81,7 @@ pub fn llvm(build: &Build, target: &str) {
        .profile(profile)
        .define("LLVM_ENABLE_ASSERTIONS", assertions)
        .define("LLVM_TARGETS_TO_BUILD",
-               "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430")
+               "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc")
        .define("LLVM_INCLUDE_EXAMPLES", "OFF")
        .define("LLVM_INCLUDE_TESTS", "OFF")
        .define("LLVM_INCLUDE_DOCS", "OFF")
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 86c40a0208a..e681a81cf0c 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -95,7 +95,8 @@ fn main() {
     let is_crossed = target != host;
 
     let optional_components =
-        ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "systemz", "jsbackend", "msp430"];
+        ["x86", "arm", "aarch64", "mips", "powerpc", "pnacl", "systemz", "jsbackend", "msp430",
+         "sparc"];
 
     // FIXME: surely we don't need all these components, right? Stuff like mcjit
     //        or interpreter the compiler itself never uses.
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index daa2617ef6e..69709f72b8b 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -371,6 +371,12 @@ pub fn initialize_available_targets() {
                  LLVMInitializeMSP430Target,
                  LLVMInitializeMSP430TargetMC,
                  LLVMInitializeMSP430AsmPrinter);
+    init_target!(llvm_component = "sparc",
+                 LLVMInitializeSparcTargetInfo,
+                 LLVMInitializeSparcTarget,
+                 LLVMInitializeSparcTargetMC,
+                 LLVMInitializeSparcAsmPrinter,
+                 LLVMInitializeSparcAsmParser);
 }
 
 pub fn last_error() -> Option<String> {
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index f0f25118990..9c4246e079b 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -24,6 +24,7 @@ use cabi_mips;
 use cabi_mips64;
 use cabi_asmjs;
 use cabi_msp430;
+use cabi_sparc;
 use machine::{llalign_of_min, llsize_of, llsize_of_alloc};
 use type_::Type;
 use type_of;
@@ -606,6 +607,7 @@ impl FnType {
             "asmjs" => cabi_asmjs::compute_abi_info(ccx, self),
             "wasm32" => cabi_asmjs::compute_abi_info(ccx, self),
             "msp430" => cabi_msp430::compute_abi_info(ccx, self),
+            "sparc" => cabi_sparc::compute_abi_info(ccx, self),
             a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a))
         }
 
diff --git a/src/librustc_trans/cabi_sparc.rs b/src/librustc_trans/cabi_sparc.rs
new file mode 100644
index 00000000000..25fe53e7ef4
--- /dev/null
+++ b/src/librustc_trans/cabi_sparc.rs
@@ -0,0 +1,108 @@
+// Copyright 2012-2013 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, Vector};
+use abi::{self, align_up_to, ArgType, FnType};
+use context::CrateContext;
+use type_::Type;
+
+fn ty_align(ty: Type) -> usize {
+    abi::ty_align(ty, 4)
+}
+
+fn ty_size(ty: Type) -> usize {
+    abi::ty_size(ty, 4)
+}
+
+fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
+    if is_reg_ty(ret.ty) {
+        ret.extend_integer_width_to(32);
+    } 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(32);
+    }
+}
+
+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))
+    } else {
+        None
+    }
+}
+
+fn coerce_to_int(ccx: &CrateContext, size: usize) -> 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), 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() { 4 } else { 0 };
+    for arg in &mut fty.args {
+        if arg.is_ignore() { continue; }
+        classify_arg_ty(ccx, arg, &mut offset);
+    }
+}
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 2fb0e8c24c5..3a8eef131a2 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -106,6 +106,7 @@ mod cabi_msp430;
 mod cabi_powerpc;
 mod cabi_powerpc64;
 mod cabi_s390x;
+mod cabi_sparc;
 mod cabi_x86;
 mod cabi_x86_64;
 mod cabi_x86_win64;
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index 73c8bb97a14..b74f4913858 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -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.
-2016-12-16
+2016-12-19