// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using Internal.TypeSystem; using Debug = System.Diagnostics.Debug; namespace ILCompiler { /// <summary> /// Represents an algorithm that computes field layout for intrinsic integer types (Int128/UInt128). /// </summary> public class Int128FieldLayoutAlgorithm : FieldLayoutAlgorithm { private readonly FieldLayoutAlgorithm _fallbackAlgorithm; public Int128FieldLayoutAlgorithm(FieldLayoutAlgorithm fallbackAlgorithm) { _fallbackAlgorithm = fallbackAlgorithm; } public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { Debug.Assert(IsIntegerType(defType)); string name = defType.GetName(); Debug.Assert((name == "Int128") || (name == "UInt128")); ComputedInstanceFieldLayout layoutFromMetadata = _fallbackAlgorithm.ComputeInstanceLayout(defType, layoutKind); // 32bit platforms use standard metadata layout engine if (defType.Context.Target.Architecture == TargetArchitecture.ARM) { layoutFromMetadata.LayoutAbiStable = true; layoutFromMetadata.IsInt128OrHasInt128Fields = true; return layoutFromMetadata; } // 64-bit Unix systems follow the System V ABI and have a 16-byte packing requirement for Int128/UInt128 return new ComputedInstanceFieldLayout { ByteCountUnaligned = layoutFromMetadata.ByteCountUnaligned, ByteCountAlignment = layoutFromMetadata.ByteCountAlignment, FieldAlignment = new LayoutInt(16), FieldSize = layoutFromMetadata.FieldSize, Offsets = layoutFromMetadata.Offsets, LayoutAbiStable = true, IsInt128OrHasInt128Fields = true }; } public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind) { return _fallbackAlgorithm.ComputeStaticFieldLayout(defType, layoutKind); } public override bool ComputeContainsGCPointers(DefType type) { Debug.Assert(!_fallbackAlgorithm.ComputeContainsGCPointers(type)); return false; } public override bool ComputeContainsByRefs(DefType type) { Debug.Assert(!_fallbackAlgorithm.ComputeContainsByRefs(type)); return false; } public override bool ComputeIsUnsafeValueType(DefType type) { Debug.Assert(!_fallbackAlgorithm.ComputeIsUnsafeValueType(type)); return false; } public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { Debug.Assert(_fallbackAlgorithm.ComputeValueTypeShapeCharacteristics(type) == ValueTypeShapeCharacteristics.None); return ValueTypeShapeCharacteristics.None; } public static bool IsIntegerType(DefType type) { return type.IsIntrinsic && type.Namespace.SequenceEqual("System"u8) && (type.Name.SequenceEqual("Int128"u8) || type.Name.SequenceEqual("UInt128"u8)); } } } |