Skip to content

Commit

Permalink
Move ty_align and ty_size out of most C ABI code
Browse files Browse the repository at this point in the history
s390x's C ABI ty_align and ty_size are not moved because the
implementation of ty_align varies in an atypical pattern: it calls
ty_size for the llvm::Vector type kind. ty_size then cannot be moved
since it indirectly calls ty_align through align.
  • Loading branch information
Mark-Simulacrum committed Sep 25, 2016
1 parent 05c2fdd commit dfe8bd1
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 395 deletions.
72 changes: 71 additions & 1 deletion src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use llvm::{self, ValueRef};
use llvm::{self, ValueRef, Integer, Pointer, Float, Double, Struct, Array, Vector};
use base;
use build::AllocaFcx;
use common::{type_is_fat_ptr, BlockAndBuilder, C_uint};
Expand Down Expand Up @@ -598,3 +598,73 @@ impl FnType {
}
}
}

pub fn align_up_to(off: usize, a: usize) -> usize {
return (off + a - 1) / a * a;
}

fn align(off: usize, ty: Type, pointer: usize) -> usize {
let a = ty_align(ty, pointer);
return align_up_to(off, a);
}

pub fn ty_align(ty: Type, pointer: usize) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => pointer,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t, pointer)))
}
}
Array => {
let elt = ty.element_type();
ty_align(elt, pointer)
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
ty_align(elt, pointer) * len
}
_ => bug!("ty_align: unhandled type")
}
}

pub fn ty_size(ty: Type, pointer: usize) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => pointer,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
let str_tys = ty.field_types();
str_tys.iter().fold(0, |s, t| s + ty_size(*t, pointer))
} else {
let str_tys = ty.field_types();
let size = str_tys.iter().fold(0, |s, t| {
align(s, *t, pointer) + ty_size(*t, pointer)
});
align(size, ty, pointer)
}
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt, pointer);
len * eltsz
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
let eltsz = ty_size(elt, pointer);
len * eltsz
},
_ => bug!("ty_size: unhandled type")
}
}
70 changes: 2 additions & 68 deletions src/librustc_trans/cabi_aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,78 +11,12 @@
#![allow(non_upper_case_globals)]

use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
use abi::{FnType, ArgType};
use abi::{self, FnType, ArgType};
use context::CrateContext;
use type_::Type;

use std::cmp;

fn align_up_to(off: usize, a: usize) -> usize {
return (off + a - 1) / a * a;
}

fn align(off: usize, ty: Type) -> usize {
let a = ty_align(ty);
return align_up_to(off, a);
}

fn ty_align(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
}
}
Array => {
let elt = ty.element_type();
ty_align(elt)
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
ty_align(elt) * len
}
_ => bug!("ty_align: unhandled type")
}
}

fn ty_size(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
let str_tys = ty.field_types();
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
} else {
let str_tys = ty.field_types();
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
align(size, ty)
}
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
_ => bug!("ty_size: unhandled type")
}
abi::ty_size(ty, 8)
}

fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> {
Expand Down
31 changes: 2 additions & 29 deletions src/librustc_trans/cabi_arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#![allow(non_upper_case_globals)]

use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
use abi::{FnType, ArgType};
use abi::{self, align_up_to, FnType, ArgType};
use context::CrateContext;
use type_::Type;

Expand All @@ -24,40 +24,13 @@ pub enum Flavor {

type TyAlignFn = fn(ty: Type) -> usize;

fn align_up_to(off: usize, a: usize) -> usize {
return (off + a - 1) / a * a;
}

fn align(off: usize, ty: Type, align_fn: TyAlignFn) -> usize {
let a = align_fn(ty);
return align_up_to(off, a);
}

fn general_ty_align(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 4,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, general_ty_align(*t)))
}
}
Array => {
let elt = ty.element_type();
general_ty_align(elt)
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
general_ty_align(elt) * len
}
_ => bug!("ty_align: unhandled type")
}
abi::ty_align(ty, 4)
}

// For more information see:
Expand Down
68 changes: 4 additions & 64 deletions src/librustc_trans/cabi_mips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,77 +13,17 @@
use libc::c_uint;
use std::cmp;
use llvm;
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
use abi::{ArgType, FnType};
use llvm::{Integer, Pointer, Float, Double, Vector};
use abi::{self, align_up_to, ArgType, FnType};
use context::CrateContext;
use type_::Type;

fn align_up_to(off: usize, a: usize) -> usize {
return (off + a - 1) / a * a;
}

fn align(off: usize, ty: Type) -> usize {
let a = ty_align(ty);
return align_up_to(off, a);
}

fn ty_align(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 4,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
}
}
Array => {
let elt = ty.element_type();
ty_align(elt)
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
ty_align(elt) * len
}
_ => bug!("ty_align: unhandled type")
}
abi::ty_align(ty, 4)
}

fn ty_size(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 4,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
let str_tys = ty.field_types();
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
} else {
let str_tys = ty.field_types();
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
align(size, ty)
}
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
_ => bug!("ty_size: unhandled type")
}
abi::ty_size(ty, 4)
}

fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
Expand Down
68 changes: 4 additions & 64 deletions src/librustc_trans/cabi_mips64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,77 +13,17 @@
use libc::c_uint;
use std::cmp;
use llvm;
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
use abi::{ArgType, FnType};
use llvm::{Integer, Pointer, Float, Double, Vector};
use abi::{self, align_up_to, ArgType, FnType};
use context::CrateContext;
use type_::Type;

fn align_up_to(off: usize, a: usize) -> usize {
return (off + a - 1) / a * a;
}

fn align(off: usize, ty: Type) -> usize {
let a = ty_align(ty);
return align_up_to(off, a);
}

fn ty_align(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
1
} else {
let str_tys = ty.field_types();
str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
}
}
Array => {
let elt = ty.element_type();
ty_align(elt)
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
ty_align(elt) * len
}
_ => bug!("ty_align: unhandled type")
}
abi::ty_align(ty, 8)
}

fn ty_size(ty: Type) -> usize {
match ty.kind() {
Integer => ((ty.int_width() as usize) + 7) / 8,
Pointer => 8,
Float => 4,
Double => 8,
Struct => {
if ty.is_packed() {
let str_tys = ty.field_types();
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
} else {
let str_tys = ty.field_types();
let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
align(size, ty)
}
}
Array => {
let len = ty.array_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
Vector => {
let len = ty.vector_length();
let elt = ty.element_type();
let eltsz = ty_size(elt);
len * eltsz
}
_ => bug!("ty_size: unhandled type")
}
abi::ty_size(ty, 8)
}

fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
Expand Down
Loading

0 comments on commit dfe8bd1

Please sign in to comment.