Skip to content

Commit

Permalink
Emit the ARM build attributes ABI_PCS_wchar_t and ABI_enum_size.
Browse files Browse the repository at this point in the history
Emit the ARM build attributes ABI_PCS_wchar_t and ABI_enum_size based on
module flags metadata.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211349 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
ostannard committed Jun 20, 2014
1 parent a5efeb6 commit e5241cc
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 0 deletions.
36 changes: 36 additions & 0 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3146,6 +3146,42 @@ Each individual option is required to be either a valid option for the target's
linker, or an option that is reserved by the target specific assembly writer or
object file emitter. No other aspect of these options is defined by the IR.

C type width Module Flags Metadata
----------------------------------

The ARM backend emits a section into each generated object file describing the
options that it was compiled with (in a compiler-independent way) to prevent
linking incompatible objects, and to allow automatic library selection. Some
of these options are not visible at the IR level, namely wchar_t width and enum
width.

To pass this information to the backend, these options are encoded in module
flags metadata, using the following key-value pairs:

.. list-table::
:header-rows: 1
:widths: 30 70

* - Key
- Value

* - short_wchar
- * 0 --- sizeof(wchar_t) == 4
* 1 --- sizeof(wchar_t) == 2

* - short_enum
- * 0 --- Enums are at least as large as an ``int``.
* 1 --- Enums are stored in the smallest integer type which can
represent all of its values.

For example, the following metadata section specifies that the module was
compiled with a ``wchar_t`` width of 4 bytes, and the underlying type of an
enum is the smallest type which can represent all of its values::

!llvm.module.flags = !{!0, !1}
!0 = metadata !{i32 1, metadata !"short_wchar", i32 1}
!1 = metadata !{i32 1, metadata !"short_enum", i32 0}

.. _intrinsicglobalvariables:

Intrinsic Global Variables
Expand Down
15 changes: 15 additions & 0 deletions include/llvm/Support/ARMBuildAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,28 @@ enum {
AddressDirect = 1, // Address imported data directly
AddressGOT = 2, // Address imported data indirectly (via GOT)

// Tag_ABI_PCS_wchar_t, (=18), uleb128
WCharProhibited = 0, // wchar_t is not used
WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4

// Tag_ABI_FP_denormal, (=20), uleb128
PreserveFPSign = 2, // sign when flushed-to-zero is preserved

// Tag_ABI_FP_number_model, (=23), uleb128
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings

// Tag_ABI_enum_size, (=26), uleb128
EnumProhibited = 0, // The user prohibited the use of enums when building
// this entity.
EnumSmallest = 1, // Enum is smallest container big enough to hold all
// values.
Enum32Bit = 2, // Enum is at least 32 bits.
Enum32BitABI = 3, // Every enumeration visible across an ABI-complying
// interface contains a value needing 32 bits to encode
// it; other enums can be containerized.

// Tag_ABI_HardFP_use, (=27), uleb128
HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
HardFPSinglePrecision = 1, // Single-precision only
Expand Down
26 changes: 26 additions & 0 deletions lib/Target/ARM/ARMAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,32 @@ void ARMAsmPrinter::emitAttributes() {
if (Subtarget->hasDivideInARMMode() && !Subtarget->hasV8Ops())
ATS.emitAttribute(ARMBuildAttrs::DIV_use, ARMBuildAttrs::AllowDIVExt);

if (MMI) {
if (const Module *SourceModule = MMI->getModule()) {
// ABI_PCS_wchar_t to indicate wchar_t width
// FIXME: There is no way to emit value 0 (wchar_t prohibited).
if (auto WCharWidthValue = cast_or_null<ConstantInt>(
SourceModule->getModuleFlag("wchar_size"))) {
int WCharWidth = WCharWidthValue->getZExtValue();
assert((WCharWidth == 2 || WCharWidth == 4) &&
"wchar_t width must be 2 or 4 bytes");
ATS.emitAttribute(ARMBuildAttrs::ABI_PCS_wchar_t, WCharWidth);
}

// ABI_enum_size to indicate enum width
// FIXME: There is no way to emit value 0 (enums prohibited) or value 3
// (all enums contain a value needing 32 bits to encode).
if (auto EnumWidthValue = cast_or_null<ConstantInt>(
SourceModule->getModuleFlag("min_enum_size"))) {
int EnumWidth = EnumWidthValue->getZExtValue();
assert((EnumWidth == 1 || EnumWidth == 4) &&
"Minimum enum width must be 1 or 4 bytes");
int EnumBuildAttr = EnumWidth == 1 ? 1 : 2;
ATS.emitAttribute(ARMBuildAttrs::ABI_enum_size, EnumBuildAttr);
}
}
}

if (Subtarget->hasTrustZone() && Subtarget->hasVirtualization())
ATS.emitAttribute(ARMBuildAttrs::Virtualization_use,
ARMBuildAttrs::AllowTZVirtualization);
Expand Down
16 changes: 16 additions & 0 deletions test/CodeGen/ARM/metadata-default.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: llc < %s -mtriple=armv7-linux-gnueabi | FileCheck %s

target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
target triple = "armv7--none-eabi"

define i32 @f(i64 %z) {
ret i32 0
}

!llvm.module.flags = !{!0, !1}

!0 = metadata !{i32 1, metadata !"wchar_size", i32 4}
!1 = metadata !{i32 1, metadata !"min_enum_size", i32 4}

; CHECK: .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t
; CHECK: .eabi_attribute 26, 2 @ Tag_ABI_enum_size
16 changes: 16 additions & 0 deletions test/CodeGen/ARM/metadata-short-enums.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: llc < %s | FileCheck %s

target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
target triple = "armv7--none-eabi"

define i32 @f(i64 %z) {
ret i32 0
}

!llvm.module.flags = !{!0, !1}

!0 = metadata !{i32 1, metadata !"wchar_size", i32 4}
!1 = metadata !{i32 1, metadata !"min_enum_size", i32 1}

; CHECK: .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t
; CHECK: .eabi_attribute 26, 1 @ Tag_ABI_enum_size
16 changes: 16 additions & 0 deletions test/CodeGen/ARM/metadata-short-wchar.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: llc < %s | FileCheck %s

target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
target triple = "armv7--none-eabi"

define i32 @f(i64 %z) {
ret i32 0
}

!llvm.module.flags = !{!0, !1}

!0 = metadata !{i32 1, metadata !"wchar_size", i32 2}
!1 = metadata !{i32 1, metadata !"min_enum_size", i32 4}

; CHECK: .eabi_attribute 18, 2 @ Tag_ABI_PCS_wchar_t
; CHECK: .eabi_attribute 26, 2 @ Tag_ABI_enum_size

0 comments on commit e5241cc

Please sign in to comment.