Skip to content

Commit 8513dd8

Browse files
committed
LayoutPositionPref
1 parent a19f934 commit 8513dd8

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

src/librustc_target/abi/mod.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,154 @@ impl AbiAndPrefAlign {
451451
}
452452
}
453453

454+
/// An aligned size preference.
455+
/// Better name appreciated.
456+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
457+
pub struct LayoutPositionPref {
458+
/// A size not rounded up to alignment
459+
pub size: Size,
460+
/// the alignment of the start of the size
461+
pub align: AbiAndPrefAlign,
462+
}
463+
464+
impl LayoutPositionPref {
465+
pub fn new_simple(size: Size, align: Align) -> LayoutPositionPref {
466+
LayoutPositionPref {
467+
size,
468+
align: AbiAndPrefAlign::new(align)
469+
}
470+
}
471+
472+
pub fn new(size: Size, align: AbiAndPrefAlign) -> LayoutPositionPref {
473+
LayoutPositionPref {
474+
size,
475+
align
476+
}
477+
}
478+
479+
#[inline]
480+
pub fn from_bits(bits: u64) -> LayoutPositionPref {
481+
// Avoid potential overflow from `bits + 7`.
482+
LayoutPositionPref::from_bytes(bits / 8 + ((bits % 8) + 7) / 8)
483+
}
484+
485+
#[inline]
486+
pub fn from_bytes(bytes: u64) -> LayoutPositionPref {
487+
LayoutPositionPref::new_simple(Size::from_bytes(bytes), Align::from_bytes(bytes).unwrap())
488+
}
489+
490+
#[inline]
491+
pub fn stride_to(self, align: Align) -> LayoutPositionPref {
492+
LayoutPositionPref::new(self.size.align_to(align), self.align)
493+
}
494+
495+
#[inline]
496+
pub fn max(self, other: LayoutPositionPref) -> LayoutPositionPref {
497+
LayoutPositionPref::new(self.size.max(other.size), self.align.max(other.align))
498+
}
499+
500+
pub fn padding_needed_for(self, align: Align) -> Size {
501+
self.stride_to(align).size - self.size
502+
}
503+
504+
pub fn repeat(self, count: u64) -> Self {
505+
return self * count
506+
}
507+
508+
pub fn extend(self, other: LayoutPositionPref) -> (Self, Size) {
509+
let p2 = self.stride_to(other.align.abi).size;
510+
(LayoutPositionPref::new(p2 + other.size, self.align), p2)
511+
}
512+
513+
#[inline]
514+
pub fn align_to(self, align: AbiAndPrefAlign) -> LayoutPositionPref {
515+
LayoutPositionPref::new(self.size, self.align.max(align))
516+
}
517+
518+
#[inline]
519+
pub fn pack_to(self, align: AbiAndPrefAlign) -> LayoutPositionPref {
520+
LayoutPositionPref::new(self.size, self.align.min(align))
521+
}
522+
523+
#[inline]
524+
pub fn align_and_stride_to(self, align: AbiAndPrefAlign) -> LayoutPositionPref {
525+
self.align_to(align).stride_to(align.abi)
526+
}
527+
528+
pub fn strided(self) -> LayoutPositionPref {
529+
self.stride_to(self.align.abi)
530+
}
531+
532+
pub fn strided_pref(self) -> LayoutPositionPref {
533+
self.stride_to(self.align.pref)
534+
}
535+
536+
pub fn stride(self) -> Size {
537+
self.strided().size
538+
}
539+
540+
pub fn pref_stride(self) -> Size {
541+
self.strided_pref().size
542+
}
543+
544+
#[inline]
545+
pub fn is_aligned(self, align: Align) -> bool {
546+
self.size.is_aligned(align)
547+
}
548+
549+
#[inline]
550+
pub fn checked_add<C: HasDataLayout>(self, other: LayoutPositionPref, cx: &C)
551+
-> Option<LayoutPositionPref> {
552+
let size = self.stride_to(other.align.abi).size.checked_add(other.size, cx)?;
553+
Some(LayoutPositionPref::new(size, self.align))
554+
}
555+
556+
#[inline]
557+
pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: &C) -> Option<LayoutPositionPref> {
558+
Some(if count == 0 {
559+
LayoutPositionPref::new(Size::ZERO, self.align)
560+
} else {
561+
LayoutPositionPref::new(self.stride().checked_mul(count - 1, cx)?, self.align) + self
562+
})
563+
}
564+
565+
}
566+
567+
impl Add for LayoutPositionPref {
568+
type Output = LayoutPositionPref;
569+
#[inline]
570+
fn add(self, other: LayoutPositionPref) -> LayoutPositionPref {
571+
self.extend(other).0
572+
}
573+
}
574+
575+
impl Mul<LayoutPositionPref> for u64 {
576+
type Output = LayoutPositionPref;
577+
#[inline]
578+
fn mul(self, size: LayoutPositionPref) -> LayoutPositionPref {
579+
size * self
580+
}
581+
}
582+
583+
impl Mul<u64> for LayoutPositionPref {
584+
type Output = LayoutPositionPref;
585+
#[inline]
586+
fn mul(self, count: u64) -> LayoutPositionPref {
587+
if count == 0 {
588+
LayoutPositionPref::new(Size::ZERO, self.align)
589+
} else {
590+
LayoutPositionPref::new(self.stride() * (count - 1), self.align) + self
591+
}
592+
}
593+
}
594+
595+
impl AddAssign for LayoutPositionPref {
596+
#[inline]
597+
fn add_assign(&mut self, other: LayoutPositionPref) {
598+
*self = *self + other;
599+
}
600+
}
601+
454602
/// Integers, also used for enum discriminants.
455603
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
456604
pub enum Integer {

0 commit comments

Comments
 (0)