}
}
+ pub fn align(&self, dl: &TargetDataLayout)-> Align {
+ match *self {
+ I1 => dl.i1_align,
+ I8 => dl.i8_align,
+ I16 => dl.i16_align,
+ I32 => dl.i32_align,
+ I64 => dl.i64_align,
+ }
+ }
+
pub fn to_ty<'a, 'tcx>(&self, tcx: &ty::TyCtxt<'a, 'tcx, 'tcx>,
signed: bool) -> Ty<'tcx> {
match (*self, signed) {
}
}
+ //Find the smallest integer with the given alignment.
+ pub fn for_abi_align(dl: &TargetDataLayout, align: Align) -> Option<Integer> {
+ let wanted = align.abi();
+ for &candidate in &[I8, I16, I32, I64] {
+ let ty = Int(candidate);
+ if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
+ return Some(candidate);
+ }
+ }
+ None
+ }
+
/// Get the Integer type from an attr::IntType.
pub fn from_attr(dl: &TargetDataLayout, ity: attr::IntType) -> Integer {
match ity {
// won't be so conservative.
// Use the initial field alignment
- let wanted = start_align.abi();
- let mut ity = min_ity;
- for &candidate in &[I16, I32, I64] {
- let ty = Int(candidate);
- if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
- ity = candidate;
- break;
- }
- }
-
- // FIXME(eddyb) conservative only to avoid diverging from trans::adt.
- if align.abi() != start_align.abi() {
- ity = min_ity;
- }
+ let mut ity = Integer::for_abi_align(dl, start_align).unwrap_or(min_ity);
// If the alignment is not larger than the chosen discriminant size,
// don't use the alignment as the final size.
fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
assert_eq!(size%align, 0);
+ assert_eq!(align.count_ones(), 1, "Alignment must be a power fof 2. Got {}", align);
let align_units = size/align;
- match align {
- 1 => Type::array(&Type::i8(cx), align_units),
- 2 => Type::array(&Type::i16(cx), align_units),
- 4 => Type::array(&Type::i32(cx), align_units),
- 8 if machine::llalign_of_min(cx, Type::i64(cx)) == 8 =>
- Type::array(&Type::i64(cx), align_units),
- a if a.count_ones() == 1 => Type::array(&Type::vector(&Type::i32(cx), a / 4),
- align_units),
- _ => bug!("unsupported union alignment: {}", align)
+ let dl = &cx.tcx().data_layout;
+ let layout_align = layout::Align::from_bytes(align, align).unwrap();
+ if let Some(ity) = layout::Integer::for_abi_align(dl, layout_align) {
+ Type::array(&Type::from_integer(cx, ity), align_units)
+ } else {
+ Type::array(&Type::vector(&Type::i32(cx), align/4),
+ align_units)
}
}