2013-04-01 19:47:38 -05:00
|
|
|
// Copyright 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.
|
|
|
|
|
2013-05-17 17:28:44 -05:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2013-04-18 16:10:13 -05:00
|
|
|
use driver::session::{os_win32, os_macos};
|
2013-04-01 19:47:38 -05:00
|
|
|
use lib::llvm::*;
|
|
|
|
use lib::llvm::llvm::*;
|
|
|
|
use super::cabi::*;
|
|
|
|
use super::common::*;
|
|
|
|
use super::machine::*;
|
|
|
|
|
|
|
|
struct X86_ABIInfo {
|
2013-06-13 02:19:50 -05:00
|
|
|
ccx: @mut CrateContext
|
2013-04-01 19:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ABIInfo for X86_ABIInfo {
|
|
|
|
fn compute_info(&self,
|
2013-06-15 22:45:48 -05:00
|
|
|
atys: &[Type],
|
|
|
|
rty: Type,
|
2013-04-01 19:47:38 -05:00
|
|
|
ret_def: bool) -> FnType {
|
|
|
|
let mut arg_tys = do atys.map |a| {
|
|
|
|
LLVMType { cast: false, ty: *a }
|
|
|
|
};
|
|
|
|
let mut ret_ty = LLVMType {
|
|
|
|
cast: false,
|
|
|
|
ty: rty
|
|
|
|
};
|
|
|
|
let mut attrs = do atys.map |_| {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
// Rules for returning structs taken from
|
|
|
|
// http://www.angelcode.com/dev/callconv/callconv.html
|
2013-04-18 16:10:13 -05:00
|
|
|
// Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
|
2013-04-01 19:47:38 -05:00
|
|
|
let sret = {
|
2013-06-15 22:45:48 -05:00
|
|
|
let returning_a_struct = unsafe { rty.kind() == Struct && ret_def };
|
2013-04-18 16:10:13 -05:00
|
|
|
let big_struct = match self.ccx.sess.targ_cfg.os {
|
|
|
|
os_win32 | os_macos => llsize_of_alloc(self.ccx, rty) > 8,
|
|
|
|
_ => true
|
2013-04-01 19:47:38 -05:00
|
|
|
};
|
|
|
|
returning_a_struct && big_struct
|
|
|
|
};
|
|
|
|
|
|
|
|
if sret {
|
|
|
|
let ret_ptr_ty = LLVMType {
|
|
|
|
cast: false,
|
2013-06-15 22:45:48 -05:00
|
|
|
ty: ret_ty.ty.ptr_to()
|
2013-04-01 19:47:38 -05:00
|
|
|
};
|
|
|
|
arg_tys = ~[ret_ptr_ty] + arg_tys;
|
|
|
|
attrs = ~[Some(StructRetAttribute)] + attrs;
|
|
|
|
ret_ty = LLVMType {
|
|
|
|
cast: false,
|
2013-06-15 22:45:48 -05:00
|
|
|
ty: Type::void(),
|
2013-04-01 19:47:38 -05:00
|
|
|
};
|
2013-06-20 09:42:44 -05:00
|
|
|
} else if !ret_def {
|
|
|
|
ret_ty = LLVMType {
|
|
|
|
cast: false,
|
|
|
|
ty: T_void()
|
|
|
|
};
|
2013-04-01 19:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return FnType {
|
|
|
|
arg_tys: arg_tys,
|
|
|
|
ret_ty: ret_ty,
|
|
|
|
attrs: attrs,
|
|
|
|
sret: sret
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-13 02:19:50 -05:00
|
|
|
pub fn abi_info(ccx: @mut CrateContext) -> @ABIInfo {
|
2013-04-01 19:47:38 -05:00
|
|
|
return @X86_ABIInfo {
|
|
|
|
ccx: ccx
|
|
|
|
} as @ABIInfo;
|
|
|
|
}
|