================
@@ -0,0 +1,241 @@
+//===---- ABITypeMapper.cpp - Maps LLVM ABI Types to LLVM IR Types ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Maps LLVM ABI type representations back to corresponding LLVM IR types.
+/// This reverse mapper translates low-level ABI-specific types back into
+/// LLVM IR types suitable for code generation and optimization passes.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ABI/ABITypeMapper.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+Type *ABITypeMapper::convertType(const abi::Type *ABIType) {
+  if (!ABIType)
+    return nullptr;
+
+  auto It = TypeCache.find(ABIType);
+  if (It != TypeCache.end())
+    return It->second;
+
+  Type *Result = nullptr;
+
+  switch (ABIType->getKind()) {
+  case abi::TypeKind::Integer:
+    Result = convertIntegerType(cast<abi::IntegerType>(ABIType));
+    break;
+  case abi::TypeKind::Float:
+    Result = convertFloatType(cast<abi::FloatType>(ABIType));
+    break;
+  case abi::TypeKind::Pointer:
+    Result = convertPointerType(cast<abi::PointerType>(ABIType));
+    break;
+  case abi::TypeKind::Array:
+    Result = convertArrayType(cast<abi::ArrayType>(ABIType));
+    break;
+  case abi::TypeKind::Vector:
+    Result = convertVectorType(cast<abi::VectorType>(ABIType));
+    break;
+  case abi::TypeKind::Struct:
+    Result = convertStructType(cast<abi::StructType>(ABIType));
+    break;
+  case abi::TypeKind::Union:
+    Result = convertUnionType(cast<abi::UnionType>(ABIType));
+    break;
+  case abi::TypeKind::Void:
+    Result = convertVoidType(cast<abi::VoidType>(ABIType));
+    break;
+  default:
+    llvm_unreachable("Unknown ABI type kind");
+  }
+
+  if (Result)
+    TypeCache[ABIType] = Result;
+
+  return Result;
+}
+
+Type *ABITypeMapper::convertIntegerType(const abi::IntegerType *IT) {
+  unsigned BitWidth = IT->getSizeInBits();
+  return IntegerType::get(Context, BitWidth);
+}
+
+Type *ABITypeMapper::convertFloatType(const abi::FloatType *FT) {
+  const fltSemantics *Semantics =
+      const_cast<abi::FloatType *>(FT)->getSemantics();
+  return getFloatTypeForSemantics(*Semantics);
+}
+
+Type *ABITypeMapper::convertPointerType(const abi::PointerType *PT) {
+  return PointerType::get(Context, 0);
+}
+
+Type *ABITypeMapper::convertArrayType(const abi::ArrayType *AT) {
+  Type *ElementType = convertType(AT->getElementType());
+  if (!ElementType)
+    return nullptr;
+
+  uint64_t NumElements = AT->getNumElements();
+
+  return ArrayType::get(ElementType, NumElements);
+}
+
+Type *ABITypeMapper::convertVectorType(const abi::VectorType *VT) {
+  Type *ElementType = convertType(VT->getElementType());
+  if (!ElementType)
+    return nullptr;
+
+  ElementCount EC = VT->getNumElements();
+
+  if (EC.isScalable())
+    return ScalableVectorType::get(ElementType, EC.getKnownMinValue());
+  return FixedVectorType::get(ElementType, EC.getFixedValue());
+}
+
+Type *ABITypeMapper::convertStructType(const abi::StructType *ST) {
+  return createStructFromFields(*ST->getFields(), ST->getNumFields(),
+                                ST->getSizeInBits(), ST->getAlignment(), 
false);
+}
+
+Type *ABITypeMapper::convertUnionType(const abi::UnionType *UT) {
+  return createStructFromFields(*UT->getFields(), UT->getNumFields(),
+                                UT->getSizeInBits(), UT->getAlignment(), true);
+}
+
+Type *ABITypeMapper::convertVoidType(const abi::VoidType *VT) {
+  return Type::getVoidTy(Context);
+}
+
+Type *ABITypeMapper::getFloatTypeForSemantics(const fltSemantics &Semantics) {
+  if (&Semantics == &APFloat::IEEEhalf())
+    return Type::getHalfTy(Context);
+  if (&Semantics == &APFloat::BFloat())
+    return Type::getBFloatTy(Context);
+  if (&Semantics == &APFloat::IEEEsingle())
+    return Type::getFloatTy(Context);
+  if (&Semantics == &APFloat::IEEEdouble())
+    return Type::getDoubleTy(Context);
+  if (&Semantics == &APFloat::x87DoubleExtended())
+    return Type::getX86_FP80Ty(Context);
+  if (&Semantics == &APFloat::IEEEquad())
+    return Type::getFP128Ty(Context);
+  if (&Semantics == &APFloat::PPCDoubleDouble())
+    return Type::getPPC_FP128Ty(Context);
+
+  // Fallback
+  return Type::getDoubleTy(Context);
+}
+
+StructType *
+ABITypeMapper::createStructFromFields(ArrayRef<abi::FieldInfo> Fields,
+                                      uint32_t NumFields, TypeSize Size,
+                                      Align Alignment, bool IsUnion) {
+  SmallVector<Type *, 16> FieldTypes;
+
+  if (IsUnion) {
+    Type *LargestFieldType = nullptr;
+    uint64_t LargestFieldSize = 0;
+
+    for (const auto &Field : Fields) {
+      Type *FieldType = convertType(Field.FieldType);
+      if (!FieldType)
+        continue;
+
+      uint64_t FieldSize = 0;
+      if (auto *IntTy = dyn_cast<IntegerType>(FieldType)) {
+        FieldSize = IntTy->getBitWidth();
+      } else if (FieldType->isFloatingPointTy()) {
+        FieldSize = FieldType->getPrimitiveSizeInBits();
+      } else if (FieldType->isPointerTy()) {
+        FieldSize = 64; // Assume 64-bit pointers
+      }
----------------
nikic wrote:

Use the SizeInBits stored in the type instead?

https://github.com/llvm/llvm-project/pull/140112
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to