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

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Wed Apr  9 17:27:02 2014
   1  // Copyright 2012-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  #![allow(non_uppercase_pattern_statics)]
  12  
  13  use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
  14  use lib::llvm::StructRetAttribute;
  15  use middle::trans::cabi::{FnType, ArgType};
  16  use middle::trans::context::CrateContext;
  17  use middle::trans::type_::Type;
  18  
  19  use std::cmp;
  20  
  21  fn align_up_to(off: uint, a: uint) -> uint {
  22      return (off + a - 1u) / a * a;
  23  }
  24  
  25  fn align(off: uint, tyType) -> uint {
  26      let a = ty_align(ty);
  27      return align_up_to(off, a);
  28  }
  29  
  30  fn ty_align(tyType) -> uint {
  31      match ty.kind() {
  32          Integer => {
  33              unsafe {
  34                  ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
  35              }
  36          }
  37          Pointer => 4,
  38          Float => 4,
  39          Double => 8,
  40          Struct => {
  41              if ty.is_packed() {
  42                  1
  43              } else {
  44                  let str_tys = ty.field_types();
  45                  str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
  46              }
  47          }
  48          Array => {
  49              let elt = ty.element_type();
  50              ty_align(elt)
  51          }
  52          _ => fail!("ty_align: unhandled type")
  53      }
  54  }
  55  
  56  fn ty_size(tyType) -> uint {
  57      match ty.kind() {
  58          Integer => {
  59              unsafe {
  60                  ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
  61              }
  62          }
  63          Pointer => 4,
  64          Float => 4,
  65          Double => 8,
  66          Struct => {
  67              if ty.is_packed() {
  68                  let str_tys = ty.field_types();
  69                  str_tys.iter().fold(0, |s, t| s + ty_size(*t))
  70              } else {
  71                  let str_tys = ty.field_types();
  72                  let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
  73                  align(size, ty)
  74              }
  75          }
  76          Array => {
  77              let len = ty.array_length();
  78              let elt = ty.element_type();
  79              let eltsz = ty_size(elt);
  80              len * eltsz
  81          }
  82          _ => fail!("ty_size: unhandled type")
  83      }
  84  }
  85  
  86  fn classify_ret_ty(ccx: &CrateContext, tyType) -> ArgType {
  87      if is_reg_ty(ty) {
  88          return ArgType::direct(ty, None, None, None);
  89      }
  90      let size = ty_size(ty);
  91      if size <= 4 {
  92          let llty = if size <= 1 {
  93              Type::i8(ccx)
  94          } else if size <= 2 {
  95              Type::i16(ccx)
  96          } else {
  97              Type::i32(ccx)
  98          };
  99          return ArgType::direct(ty, Some(llty), None, None);
 100      }
 101      ArgType::indirect(ty, Some(StructRetAttribute))
 102  }
 103  
 104  fn classify_arg_ty(ccx: &CrateContext, tyType) -> ArgType {
 105      if is_reg_ty(ty) {
 106          return ArgType::direct(ty, None, None, None);
 107      }
 108      let align = ty_align(ty);
 109      let size = ty_size(ty);
 110      let llty = if align <= 4 {
 111          Type::array(&Type::i32(ccx), ((size + 3) / 4) as u64)
 112      } else {
 113          Type::array(&Type::i64(ccx), ((size + 7) / 8) as u64)
 114      };
 115      ArgType::direct(ty, Some(llty), None, None)
 116  }
 117  
 118  fn is_reg_ty(tyType) -> bool {
 119      match ty.kind() {
 120          Integer
 121          | Pointer
 122          | Float
 123          | Double => true,
 124          _ => false
 125      }
 126  }
 127  
 128  pub fn compute_abi_info(ccx: &CrateContext,
 129                          atys: &[Type],
 130                          rtyType,
 131                          ret_def: bool) -> FnType {
 132      let mut arg_tys = Vec::new();
 133      for &aty in atys.iter() {
 134          let ty = classify_arg_ty(ccx, aty);
 135          arg_tys.push(ty);
 136      }
 137  
 138      let ret_ty = if ret_def {
 139          classify_ret_ty(ccx, rty)
 140      } else {
 141          ArgType::direct(Type::void(ccx), None, None, None)
 142      };
 143  
 144      return FnType {
 145          arg_tys: arg_tys,
 146          ret_ty: ret_ty,
 147      };
 148  }


librustc/middle/trans/cabi_arm.rs:29:1-29:1 -fn- definition:
fn ty_align(ty: Type) -> uint {
    match ty.kind() {
        Integer => {
references:- 4
25: fn align(off: uint, ty: Type) -> uint {
26:     let a = ty_align(ty);
27:     return align_up_to(off, a);
--
44:                 let str_tys = ty.field_types();
45:                 str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
46:             }
--
107:     }
108:     let align = ty_align(ty);
109:     let size = ty_size(ty);


librustc/middle/trans/cabi_arm.rs:55:1-55:1 -fn- definition:
fn ty_size(ty: Type) -> uint {
    match ty.kind() {
        Integer => {
references:- 5
108:     let align = ty_align(ty);
109:     let size = ty_size(ty);
110:     let llty = if align <= 4 {


librustc/middle/trans/cabi_arm.rs:117:1-117:1 -fn- definition:
fn is_reg_ty(ty: Type) -> bool {
    match ty.kind() {
        Integer
references:- 2
86: fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
87:     if is_reg_ty(ty) {
88:         return ArgType::direct(ty, None, None, None);
--
104: fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
105:     if is_reg_ty(ty) {
106:         return ArgType::direct(ty, None, None, None);


librustc/middle/trans/cabi_arm.rs:24:1-24:1 -fn- definition:
fn align(off: uint, ty: Type) -> uint {
    let a = ty_align(ty);
    return align_up_to(off, a);
references:- 2
71:                 let str_tys = ty.field_types();
72:                 let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
73:                 align(size, ty)
74:             }