(index<- )        ./librustc/middle/trans/cabi_x86.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Wed Mar 26 11:50:03 2014
  1  // Copyright 2013 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  
 12  use syntax::abi::{OsWin32, OsMacos};
 13  use lib::llvm::*;
 14  use super::cabi::*;
 15  use super::common::*;
 16  use super::machine::*;
 17  use middle::trans::type_::Type;
 18  
 19  pub fn compute_abi_info(ccx: &CrateContext,
 20                          atys: &[Type],
 21                          rtyType,
 22                          ret_def: bool) -> FnType {
 23      let mut arg_tys = Vec::new();
 24  
 25      let ret_ty;
 26      if !ret_def {
 27          ret_ty = ArgType::direct(Type::void(ccx), None, None, None);
 28      } else if rty.kind() == Struct {
 29          // Returning a structure. Most often, this will use
 30          // a hidden first argument. On some platforms, though,
 31          // small structs are returned as integers.
 32          //
 33          // Some links:
 34          // http://www.angelcode.com/dev/callconv/callconv.html
 35          // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
 36  
 37          enum Strategy { RetValue(Type), RetPointer }
 38          let strategy = match ccx.sess().targ_cfg.os {
 39              OsWin32 | OsMacos => {
 40                  match llsize_of_alloc(ccx, rty) {
 41                      1 => RetValue(Type::i8(ccx)),
 42                      2 => RetValue(Type::i16(ccx)),
 43                      4 => RetValue(Type::i32(ccx)),
 44                      8 => RetValue(Type::i64(ccx)),
 45                      _ => RetPointer
 46                  }
 47              }
 48              _ => {
 49                  RetPointer
 50              }
 51          };
 52  
 53          match strategy {
 54              RetValue(t) => {
 55                  ret_ty = ArgType::direct(rty, Some(t), None, None);
 56              }
 57              RetPointer => {
 58                  ret_ty = ArgType::indirect(rty, Some(StructRetAttribute));
 59              }
 60          }
 61      } else {
 62          ret_ty = ArgType::direct(rty, None, None, None);
 63      }
 64  
 65      for &t in atys.iter() {
 66          let ty = match t.kind() {
 67              Struct => {
 68                  let size = llsize_of_alloc(ccx, t);
 69                  if size == 0 {
 70                      ArgType::ignore(t)
 71                  } else {
 72                      ArgType::indirect(t, Some(ByValAttribute))
 73                  }
 74              }
 75              _ => ArgType::direct(t, None, None, None),
 76          };
 77          arg_tys.push(ty);
 78      }
 79  
 80      return FnType {
 81          arg_tys: arg_tys,
 82          ret_ty: ret_ty,
 83      };
 84  }