Move ty_align and ty_size out of most C ABI code

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.
This commit is contained in:
Mark-Simulacrum 2016-09-24 18:19:56 -06:00
parent 05c2fdd64f
commit dfe8bd10fe
9 changed files with 103 additions and 395 deletions

View File

@ -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};
@ -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")
}
}

View File

@ -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)> {

View File

@ -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;
@ -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:

View File

@ -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) {

View File

@ -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) {

View File

@ -10,67 +10,26 @@
use libc::c_uint;
use llvm;
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
use abi::{FnType, ArgType};
use llvm::{Integer, Pointer, Float, Double, Vector};
use abi::{self, align_up_to, 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 => 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)
}
_ => bug!("ty_size: unhandled type")
if ty.kind() == Vector {
bug!("ty_size: unhandled type")
} else {
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
}
_ => bug!("ty_size: unhandled type")
if ty.kind() == Vector {
bug!("ty_size: unhandled type")
} else {
abi::ty_size(ty, 4)
}
}

View File

@ -15,67 +15,16 @@
// Alignment of 128 bit types is not currently handled, this will
// need to be fixed when PowerPC vector support is added.
use llvm::{Integer, Pointer, Float, Double, Struct, Array};
use abi::{FnType, ArgType};
use llvm::{Integer, Pointer, Float, Double, Struct, Vector, Array};
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)
}
_ => 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
}
_ => bug!("ty_size: unhandled type")
if ty.kind() == Vector {
bug!("ty_size: unhandled type")
} else {
abi::ty_size(ty, 8)
}
}

View File

@ -12,16 +12,12 @@
// for a pre-z13 machine or using -mno-vx.
use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
use abi::{FnType, ArgType};
use abi::{align_up_to, 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);

View File

@ -16,12 +16,10 @@ use self::RegClass::*;
use llvm::{Integer, Pointer, Float, Double};
use llvm::{Struct, Array, Attribute, Vector};
use abi::{ArgType, FnType};
use abi::{self, ArgType, FnType};
use context::CrateContext;
use type_::Type;
use std::cmp;
#[derive(Clone, Copy, PartialEq)]
enum RegClass {
NoClass,
@ -90,62 +88,11 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
}
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 => {
let str_tys = ty.field_types();
if ty.is_packed() {
str_tys.iter().fold(0, |s, t| s + ty_size(*t))
} else {
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 all_mem(cls: &mut [RegClass]) {