187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===- ARMELFAttributeData.h ----------------------------------------------===// 287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// The MCLinker Project 487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// This file is distributed under the University of Illinois Open Source 687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// License. See LICENSE.TXT for details. 787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===----------------------------------------------------------------------===// 987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include "ARMELFAttributeData.h" 1087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Input.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/LEB128.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/ADT/STLExtras.h> 1687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst ELFAttributeValue* ARMELFAttributeData::getAttributeValue( 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines TagType pTag) const { 2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pTag <= Tag_Max) { 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& attr_value = m_Attrs[pTag]; 2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (attr_value.isInitialized()) { 2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return &attr_value; 2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Don't return uninitialized attribute value. 2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return NULL; 2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 3187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines UnknownAttrsMap::const_iterator attr_it = m_UnknownAttrs.find(pTag); 3287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 3387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (attr_it == m_UnknownAttrs.end()) { 3487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return NULL; 3587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return &attr_it->second; 3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstd::pair<ELFAttributeValue*, bool> 4237b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMELFAttributeData::getOrCreateAttributeValue(TagType pTag) { 4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue* attr_value = NULL; 4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pTag <= Tag_Max) { 4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines attr_value = &m_Attrs[pTag]; 4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // An unknown tag encounterred. 4987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines attr_value = &m_UnknownAttrs[pTag]; 5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(attr_value != NULL); 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Setup the value type. 5587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!attr_value->isUninitialized()) { 5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return std::make_pair(attr_value, false); 5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines attr_value->setType(GetAttributeValueType(pTag)); 5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return std::make_pair(attr_value, true); 6087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesunsigned int ARMELFAttributeData::GetAttributeValueType(TagType pTag) { 6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // See ARM [ABI-addenda], 2.2.6. 6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (pTag) { 6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_compatibility: { 6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return (ELFAttributeValue::Int | ELFAttributeValue::String); 6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_nodefaults: { 7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return (ELFAttributeValue::Int | ELFAttributeValue::NoDefault); 7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_raw_name: 7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_name: { 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return ELFAttributeValue::String; 7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: { 7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pTag < 32) 7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return ELFAttributeValue::Int; 7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines return ((pTag & 1) ? ELFAttributeValue::String 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines : ELFAttributeValue::Int); 8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // unreachable 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Helper Functions for merge() 8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace { 9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Helper function to decode value in Tag_also_compatible_with. 9587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * 9687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * @ref ARM [ABI-addenda], 2.3.7.3 9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic int decode_secondary_compatibility_attribute( 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& pValue) { 10087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The encoding of Tag_also_compatible_with is: 10187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_also_compatible_with (=65), NTSB: data 10387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 10487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The data can be either an ULEB128-encoded number followed by a NULL byte or 10587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // a NULL-terminated string. Currently, only the following byte sequence in 10687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // data are currently defined: 10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_CPU_arch (=6) [The arch] 0 10987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert((pValue.type() == ELFAttributeValue::String) && 11087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines "Value of Tag_also_compatible_with must be a string!"); 11187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines const std::string& data = pValue.getStringValue(); 11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Though the integer is in LEB128 format, but they occupy only 1 byte in 11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // currently defined value. 11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (data.length() < 2) 11787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Must have a byte for Tag_CPU_arch (=6) 11887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // a byte for specifying the CPU architecture (CPU_Arch_ARM_*) 11987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 12087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Currently, the 2nd byte can only be v4T (=2) or v6-M (=11). 12187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return -1; 12287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 12387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((static_cast<uint8_t>(data[0]) == ARMELFAttributeData::Tag_CPU_arch) && 12487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ((data[1] == ARMELFAttributeData::CPU_Arch_ARM_V4T) || 12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (data[1] == ARMELFAttributeData::CPU_Arch_ARM_V6_M))) 12687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return static_cast<uint32_t>(data[1]); 12787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 12887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_also_compatible_with can be safely ignored. 12987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return -1; 13087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 13187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 13287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 13387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * This helper array keeps the ordering of the values in attributes such as 13487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Tag_ABI_align_needed which are sored as 1 > 2 > 0. 13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 13637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const int value_ordering_120[] = {0, 2, 1}; 13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // anonymous namespace 13987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 14187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// End Helper Functions for merge() 14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 14387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 14487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool ARMELFAttributeData::merge(const LinkerConfig& pConfig, 14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Input& pInput, 14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines TagType pTag, 14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& pInAttr) { 14887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Pre-condition 14987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. The out_attr must be initailized and has value of the same type as 15087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // pInAttr. 15187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. The value helf by out_attr and pInAttr must be different. 15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_attr = m_Attrs[pTag]; 15387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 15487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Attribute in the output must have value assigned. 15587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_attr.isInitialized() && "No output attribute to be merged!"); 15687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 15787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (pTag) { 15887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_arch: { 15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Need value of Tag_also_compatible_with in the input for merge. 16087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() <= CPU_Arch_Max) { 16187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_CPUArch = pInAttr.getIntValue(); 16287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 16387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines error(diag::error_unknown_cpu_arch) << pInput.name(); 16487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 16587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 16687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 16787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 16887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_name: { 16987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // need value of Tag_CPU_arch in the input for merge 17087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_CPUName = pInAttr.getStringValue(); 17187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 17287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 17387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_raw_name: { 17487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // need value of Tag_CPU_arch in the input for merge 17587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_CPURawName = pInAttr.getStringValue(); 17687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 17787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 17887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_FP_arch: { 17987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // need value of Tag_HardFP_use in the input for merge 18087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_FPArch = pInAttr.getIntValue(); 18187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 18287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 18387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_HardFP_use: { 18487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // need value of Tag_FP_arch in the input for merge 18587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_HardFPUse = pInAttr.getIntValue(); 18687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 18787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 18887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_also_compatible_with: { 18987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // need value of Tag_CPU_arch in the input for merge 19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_SecondaryCPUArch = decode_secondary_compatibility_attribute(pInAttr); 19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 19387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_VFP_args: { 19487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // need value of Tag_ABI_FP_number_model in the input for merge 19587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_VFPArgs = pInAttr.getIntValue(); 19687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The value of these tags are integers and after merge, only the greatest 19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // value held by pInAttr and out_attr goes into output. 20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ARM_ISA_use: 20187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_THUMB_ISA_use: 20287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_WMMX_arch: 20387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_Advanced_SIMD_arch: 20487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_rounding: 20587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_exceptions: 20687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_user_exceptions: 20787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_number_model: 20887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_FP_HP_extension: 20987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_unaligned_access: 21087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_T2EE_use: { 21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert((out_attr.type() == ELFAttributeValue::Int) && 21287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (pInAttr.type() == ELFAttributeValue::Int) && 21337b74a387bb3993387029859c2d9d051c41c724eStephen Hines "should have integer parameeter!"); 21487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() > out_attr.getIntValue()) 21587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 21687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 21787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 21887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The value of these tags are integers and after merge, only the smallest 21987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // value held by pInAttr and out_attr goes into output. 22087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_align_preserved: 22187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_PCS_RO_data: { 22287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert((out_attr.type() == ELFAttributeValue::Int) && 22387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (pInAttr.type() == ELFAttributeValue::Int) && 22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines "should have integer parameeter!"); 22587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() < out_attr.getIntValue()) 22687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 22987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The values of these attributes are sorted as 1 > 2 > 0. And the greater 23087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // value becomes output. 23187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_align_needed: 23287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_denormal: 23387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_PCS_GOT_use: { 23487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const int in_val = pInAttr.getIntValue(); 23587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const int out_val = out_attr.getIntValue(); 23687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 23787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (in_val <= 2) { 23887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_val <= 2) { 23987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Use value_ordering_120 to determine the ordering. 24087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (value_ordering_120[in_val] > value_ordering_120[out_val]) { 24187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(in_val); 24287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 24387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 24487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 24587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // input value > 2, for future-proofing 24687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (in_val > out_val) { 24787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(in_val); 24887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 24987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 25087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 25187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 25287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // These tags use the first value ever seen. 25387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_optimization_goals: 25487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_optimization_goals: { 25587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 25687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 25787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_CPU_arch_profile 25887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_CPU_arch_profile: { 25987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() == Arch_Profile_None) 26087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 26187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 26287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (out_attr.getIntValue()) { 26387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Arch_Profile_None: { 26487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 26587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 26687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 26787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Arch_Profile_RealOrApp: { 26887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() != Arch_Profile_Microcontroller) 26987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 27087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 27187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_cpu_arch_profile) 27287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines << pInAttr.getIntValue() << pInput.name(); 27387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 27487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 27587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: { 27687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // out_attr is Arch_Profile_Application or Arch_Profile_Realtime or 27787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Arch_Profile_Microcontroller. 27887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pInAttr.getIntValue() == Arch_Profile_RealOrApp) && 27987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (out_attr.getIntValue() != Arch_Profile_Microcontroller)) { 28087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // do nothing 28187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 28287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 28387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_cpu_arch_profile) 28487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines << pInAttr.getIntValue() << pInput.name(); 28587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 28687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 28787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 28887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 28987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 29087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 29187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_MPextension_use and Tag_MPextension_use_legacy 29287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_MPextension_use: 29387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_MPextension_use_legacy: { 29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_MPextensionUse < 0) { 29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_MPextensionUse = pInAttr.getIntValue(); 29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (static_cast<unsigned>(m_MPextensionUse) != pInAttr.getIntValue()) { 29887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::error_mismatch_mpextension_use) << pInput.name(); 29987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 30087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 30187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 30287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 30387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_DIV_use 30487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_DIV_use: { 30587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() == 2) { 30687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2 means the code was permitted to use SDIV/UDIV in anyway. 30787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(2); 30887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 30987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Merge until settling down Tag_CPU_arch. 31087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_DIVUse = pInAttr.getIntValue(); 31187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 31287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 31387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_enum_size 31587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_enum_size: { 31687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((out_attr.getIntValue() == Enum_Unused) || 31787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (out_attr.getIntValue() == Enum_Containerized_As_Possible)) 31887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 31987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if (pInAttr.getIntValue() != Enum_Containerized_As_Possible && 32087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pConfig.options().warnMismatch()) 32187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_enum_size) 32237b74a387bb3993387029859c2d9d051c41c724eStephen Hines << pInput.name() << pInAttr.getIntValue() << out_attr.getIntValue(); 32387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 32487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_FP_16bit_format 32687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_FP_16bit_format: { 32787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 0: doesn't use any 16-bit FP number 32887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1: use IEEE 754 format 16-bit FP number 32987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2: use VFPv3/Advanced SIMD "alternative format" 16-bit FP number 33087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() != 0) { 33187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_attr.getIntValue() == 0) { 33287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 33387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 33487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 33587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_fp16_format) << pInput.name(); 33687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 33787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 33887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 33987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 34087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_nodefaults 34187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_nodefaults: { 34287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // There's nothing to do for this tag. It doesn't have an actual value. 34387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 34487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 34587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_conformance 34687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_conformance: { 34787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Throw away the value if the attribute value doesn't match. 34887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_attr.getStringValue() != pInAttr.getStringValue()) 34987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setStringValue(""); 35087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 35187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 35287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_Virtualization_use 35387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_Virtualization_use: { 35487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 0: No use of any virtualization extension 35587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1: TrustZone 35687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2: Virtualization extension such as HVC and ERET 35787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3: TrustZone and virtualization extension are permitted 35887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() != 0) { 35987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_attr.getIntValue() == 0) { 36087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 36187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 36287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((out_attr.getIntValue() <= 3) && (pInAttr.getIntValue() <= 3)) { 36387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Promote to 3 36487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(3); 36587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 36687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_unrecognized_virtualization_use) 36787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines << pInput.name() << pInAttr.getIntValue(); 36887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 36987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 37087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 37187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 37287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 37387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_WMMX_args 37487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_WMMX_args: { 37587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // There's no way to merge this value (i.e., objects contain different 37687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // value in this tag are definitely incompatible.) 37787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 37887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_abi_wmmx_args) << pInput.name(); 37987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 38087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 38187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_PCS_config 38287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_PCS_config: { 38387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 0 means no standard configuration used or no information recorded. 38487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() != 0) { 38587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_attr.getIntValue() == 0) 38687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 38787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 38887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Different values in these attribute are conflict 38987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 39087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_pcs_config) << pInput.name(); 39187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 39287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 39387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 39487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 39587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_PCS_R9_use 39687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_PCS_R9_use: { 39787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() != R9_Unused) { 39887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_attr.getIntValue() == R9_Unused) 39987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 40087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 40287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_r9_use) << pInput.name(); 40387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 40487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 40787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_PCS_RW_data 40887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_PCS_RW_data: { 40987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() == RW_data_SB_Relative) { 41087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Require using R9 as SB (global Static Base register). 41187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((out_attr.getIntValue() != R9_Unused) && 41287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (out_attr.getIntValue() != R9_SB) && 41387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pConfig.options().warnMismatch()) 41487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_r9_use) << pInput.name(); 41587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 41687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Choose the smaller value 41787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() < out_attr.getIntValue()) 41887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 41987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 42087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 42187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_PCS_wchar_t 42287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case Tag_ABI_PCS_wchar_t: { 42387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 0: no use of wchar_t 42487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2: sizeof(wchar_t) = 2 42587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 4: sizeof(wchar_t) = 4 42687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pInAttr.getIntValue() != 0) { 42787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_attr.getIntValue() == 0) 42887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(pInAttr.getIntValue()); 42987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else { 43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 43137b74a387bb3993387029859c2d9d051c41c724eStephen Hines warning(diag::warn_mismatch_wchar_size) << pInput.name() 43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines << pInAttr.getIntValue() 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines << out_attr.getIntValue(); 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 43787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines default: { 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Handle unknown attributes: 44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Since we don't know how to merge the value of unknown attribute, we 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // have to ignore it. There're two rules related to the processing (See 44387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // ARM [ABI-addenda] 2.2.6, Coding extensibility and compatibility.): 44487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1. For tag N where N >= 128, tag N has the same properties as 44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // tag N % 128. 44787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2. Tag 64-127 can be safely ignored. 44887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3. Tag 0-63 must be comprehended, therefore we cannot ignore. 44987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) { 45087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pTag & 127) < 64) { 45187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_unknown_mandatory_attribute) << pTag 45287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines << pInput.name(); 45387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 45487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_unknown_attribute) << pTag << pInput.name(); 45587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 45687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 45787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 45887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 45987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 46087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 46187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 46287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 46387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 46487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Helper Functions for postMerge() 46587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 46687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 46787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesnamespace { 46887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 46987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 47087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Helper function to encode value in Tag_also_compatible_with. 47187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * 47287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * @ref ARM [ABI-addenda], 2.3.7.3 47387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 47437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic void encode_secondary_compatibility_attribute(ELFAttributeValue& pValue, 47537b74a387bb3993387029859c2d9d051c41c724eStephen Hines int pArch) { 47687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((pArch < 0) || (pArch > ARMELFAttributeData::CPU_Arch_Max)) { 47787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pValue.setStringValue(""); 47887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 47987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines char new_value[] = { 48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ARMELFAttributeData::Tag_CPU_arch, static_cast<char>(pArch), 0}; 48187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines pValue.setStringValue(std::string(new_value, sizeof(new_value))); 48287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 48387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 48487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 48687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 48787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Combine the main and secondary CPU arch value 48887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 48937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic int calculate_cpu_arch(int cpu_arch, int secondary_arch) { 49087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // short-circuit 49187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((secondary_arch < 0) || 49287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ((cpu_arch + secondary_arch) != (ARMELFAttributeData::CPU_Arch_ARM_V4T + 49387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMELFAttributeData::CPU_Arch_ARM_V6_M))) 49487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return cpu_arch; 49587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 49687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((cpu_arch == ARMELFAttributeData::CPU_Arch_ARM_V4T) && 49787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (secondary_arch == ARMELFAttributeData::CPU_Arch_ARM_V6_M)) 49887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return ARMELFAttributeData::CPU_Arch_ARM_V4T_Plus_V6_M; 49987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else if ((cpu_arch == ARMELFAttributeData::CPU_Arch_ARM_V6_M) && 50087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (secondary_arch == ARMELFAttributeData::CPU_Arch_ARM_V4T)) 50187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return ARMELFAttributeData::CPU_Arch_ARM_V4T_Plus_V6_M; 50287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines else 50387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return cpu_arch; 50487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 50587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 50687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 50787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Given a CPU arch X and a CPU arch Y in which Y is newer than X, the value in 50887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * cpu_compatibility_table[X][Y] is the CPU arch required to run ISA both from X 50987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * and Y. 0 in the table means unreachable and -1 means conflict architecture 51087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * profile. 51187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 51287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#define CPU(C) ARMELFAttributeData::CPU_Arch_ARM_ ## C 51337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const int cpu_compatibility_table[][CPU(V4T_Plus_V6_M) + 1] = { 51437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* old\new ARM v6T2 ARM v6K ARM v7 ARM v6-M ARM v6S-M ARM v7E-M ARMv8, ARM v4t + v6-M */ // NOLINT 51537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* Pre v4 */ { CPU(V6T2), CPU(V6K), CPU(V7), -1, -1, -1, -1, -1 }, // NOLINT 51637b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v4 */ { CPU(V6T2), CPU(V6K), CPU(V7), -1, -1, -1, -1, -1 }, // NOLINT 51737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v4T */ { CPU(V6T2), CPU(V6K), CPU(V7), CPU(V6K), CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V4T) }, // NOLINT 51837b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v5T */ { CPU(V6T2), CPU(V6K), CPU(V7), CPU(V6K), CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V5T) }, // NOLINT 51937b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v5TE */ { CPU(V6T2), CPU(V6K), CPU(V7), CPU(V6K), CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V5TE) }, // NOLINT 52037b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v5TEJ */ { CPU(V6T2), CPU(V6K), CPU(V7), CPU(V6K), CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V5TEJ) }, // NOLINT 52137b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6 */ { CPU(V6T2), CPU(V6K), CPU(V7), CPU(V6K), CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V6) }, // NOLINT 52237b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6KZ */ { CPU(V7), CPU(V6KZ), CPU(V7), CPU(V6KZ), CPU(V6KZ), CPU(V7E_M), CPU(V8), CPU(V6KZ) }, // NOLINT 52337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6T2 */ { CPU(V6T2), CPU(V7), CPU(V7), CPU(V7), CPU(V7), CPU(V7E_M), CPU(V8), CPU(V6T2) }, // NOLINT 52437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6K */ { 0, CPU(V6K), CPU(V7), CPU(V6K), CPU(V6K), CPU(V7E_M), CPU(V8), CPU(V6K) }, // NOLINT 52537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v7 */ { 0, 0, CPU(V7), CPU(V7), CPU(V7), CPU(V7E_M), CPU(V8), CPU(V7) }, // NOLINT 52637b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6-M */ { 0, 0, 0, CPU(V6_M), CPU(V6S_M), CPU(V7E_M), CPU(V8), CPU(V6_M) }, // NOLINT 52737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6S-M */ { 0, 0, 0, 0, CPU(V6S_M), CPU(V7E_M), CPU(V8), CPU(V6S_M) }, // NOLINT 52837b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v7E-M */ { 0, 0, 0, 0, 0, CPU(V7E_M), CPU(V8), CPU(V7E_M) }, // NOLINT 52937b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v8 */ { 0, 0, 0, 0, 0, 0, CPU(V8), CPU(V8) }, // NOLINT 53037b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* v4T + v6-M */ { 0, 0, 0, 0, 0, 0, 0, CPU(V4T_Plus_V6_M) } // NOLINT 53187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 53287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 53387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 53487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Helper function to determine the merge of two different CPU arch. 53587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 53637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic int merge_cpu_arch(int out_cpu_arch, int in_cpu_arch) { 53787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_cpu_arch > CPU(V4T_Plus_V6_M)) 53887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return in_cpu_arch; 53987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 54087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int new_cpu_arch, old_cpu_arch; 54187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_cpu_arch > in_cpu_arch) { 54287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines new_cpu_arch = out_cpu_arch; 54387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines old_cpu_arch = in_cpu_arch; 54487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 54587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines new_cpu_arch = in_cpu_arch; 54687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines old_cpu_arch = out_cpu_arch; 54787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 54887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 54987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // No need to check the compatibility since the CPU architectures before 55087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // V6KZ add features monotonically. 55187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (new_cpu_arch <= CPU(V6KZ)) 55287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return new_cpu_arch; 55387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 55487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return cpu_compatibility_table[old_cpu_arch][new_cpu_arch - CPU(V6T2)]; 55587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 55687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#undef CPU 55787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 55887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 55987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Generic CPU name is used when Tag_CPU_name is unable to guess during the 56087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * merge of Tag_CPU_arch. 56187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 56287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstatic const char* generic_cpu_name_table[] = { 56337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* Pre v4 */ "Pre v4", 56437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* Pre v4 */ "ARM v4", 56537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v4T */ "ARM v4T", 56637b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v5T */ "ARM v5T", 56737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v5TE */ "ARM v5TE", 56837b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v5TEJ */ "ARM v5TEJ", 56937b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6 */ "ARM v6", 57037b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6KZ */ "ARM v6KZ", 57137b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6T2 */ "ARM v6T2", 57237b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6K */ "ARM v6K", 57337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v7 */ "ARM v7", 57437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6-M */ "ARM v6-M", 57537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v6S-M */ "ARM v6S-M", 57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v7E-M */ "ARM v7E-M", 57737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* ARM v8 */ "ARM v8", 57887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 57987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 58087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstatic const char* get_generic_cpu_name(int cpu_arch) { 581533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines assert(static_cast<size_t>(cpu_arch) < 582533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines (sizeof(generic_cpu_name_table) / sizeof(generic_cpu_name_table[0]))); 58387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return generic_cpu_name_table[cpu_arch]; 58487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 58587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 58687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/* 58787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines * Helper functions & data used in the merge of two different FP arch. 58887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines */ 58987f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstatic const struct fp_config_data { 59087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int version; 59187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int regs; 59287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} fp_configs[] = { 59337b74a387bb3993387029859c2d9d051c41c724eStephen Hines {0, 0}, 59437b74a387bb3993387029859c2d9d051c41c724eStephen Hines {1, 16}, 59537b74a387bb3993387029859c2d9d051c41c724eStephen Hines {2, 16}, 59637b74a387bb3993387029859c2d9d051c41c724eStephen Hines {3, 32}, 59737b74a387bb3993387029859c2d9d051c41c724eStephen Hines {3, 16}, 59837b74a387bb3993387029859c2d9d051c41c724eStephen Hines {4, 32}, 59937b74a387bb3993387029859c2d9d051c41c724eStephen Hines {4, 16}, 60037b74a387bb3993387029859c2d9d051c41c724eStephen Hines {8, 32}, 60137b74a387bb3993387029859c2d9d051c41c724eStephen Hines {8, 16}, 60287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 60387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 60487f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesstatic const size_t num_fp_configs = 60587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sizeof(fp_configs) / sizeof(fp_config_data); 60687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 60787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// Given h(x, y) = (x * (y >> 4) + (y >> 5)) 60887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 60987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(0, 0) = 0 ] = 0 61087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(1, 16) = 1 ] = 1 61187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(2, 16) = 2 ] = 2 61287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(3, 32) = 7 ] = 3 61387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(3, 16) = 3 ] = 4 61487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(4, 32) = 9 ] = 5 61587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(4, 16) = 4 ] = 6 61687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(8, 32) = 17 ] = 7 61787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// fp_config_hash_table[ h(8, 16) = 8 ] = 8 61887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// 61987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// h(0, 0) = 0 62037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const uint8_t fp_config_hash_table[] = { 62187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#define UND static_cast<uint8_t>(-1) 62237b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 0 */ 0, 62337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 1 */ 1, 62437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 2 */ 2, 62537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 3 */ 4, 62637b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 4 */ 6, 62737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 5 */ UND, 62837b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 6 */ UND, 62937b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 7 */ 3, 63037b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 8 */ 8, 63137b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 9 */ 5, 63237b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 10 */ UND, 63337b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 11 */ UND, 63437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 12 */ UND, 63537b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 13 */ UND, 63637b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 14 */ UND, 63737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 15 */ UND, 63837b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 16 */ UND, 63937b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* 17 */ 7, 64087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#undef UND 64187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}; 64287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 64337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic int calculate_fp_config_hash(const struct fp_config_data& pConfig) { 64487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int x = pConfig.version; 64587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int y = pConfig.regs; 64687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return (x * (y >> 4) + (y >> 5)); 64787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 64887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 64937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic int get_fp_arch_of_config(const struct fp_config_data& pConfig) { 65087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int hash = calculate_fp_config_hash(pConfig); 65137b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(static_cast<size_t>(hash) < 65237b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::array_lengthof(fp_config_hash_table)); 65387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return fp_config_hash_table[hash]; 65487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 65587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 65637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic bool is_allowed_use_of_div(int cpu_arch, 65737b74a387bb3993387029859c2d9d051c41c724eStephen Hines int cpu_arch_profile, 65887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int div_use) { 65987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 0: The code was permitted to use SDIV and UDIV in the Thumb ISA on v7-R or 66087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // v7-M. 66187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1: The code was not permitted to use SDIV and UDIV. 66287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2: The code was explicitly permitted to use SDIV and UDIV. 66387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines switch (div_use) { 66487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case 0: { 66587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((cpu_arch == ARMELFAttributeData::CPU_Arch_ARM_V7) && 66687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ((cpu_arch_profile == 'R') || (cpu_arch_profile == 'M'))) { 66787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 66887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 66987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return (cpu_arch >= ARMELFAttributeData::CPU_Arch_ARM_V7E_M); 67087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 67187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 67287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case 1: { 67387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 67487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 67587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines case 2: 67687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // For future proofing 67737b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: { return true; } 67887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 67987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 68087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 68137b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // anonymous namespace 68287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 68387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 68487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// End Helper Functions for postMerge() 68587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines//===--------------------------------------------------------------------===// 68687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 68787f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesbool ARMELFAttributeData::postMerge(const LinkerConfig& pConfig, 68837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Input& pInput) { 68987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Process Tag_CPU_arch, Tag_CPU_name, Tag_CPU_raw_name, and 69087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_also_compatible_with. 69137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_cpu_arch_attr = m_Attrs[Tag_CPU_arch]; 69237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_secondary_compatibility_attr = 69387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_Attrs[Tag_also_compatible_with]; 69487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 69587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((m_CurrentCPUArch < 0) && out_cpu_arch_attr.isInitialized()) { 69687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Current input initializes the value of Tag_CPU_arch. Validate it. 69787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int out_cpu_arch = out_cpu_arch_attr.getIntValue(); 69887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 69987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_cpu_arch > CPU_Arch_Max) { 70087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines error(diag::error_unknown_cpu_arch) << pInput.name(); 70187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 70287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 70387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 70487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Initialize m_CurrentCPUArch. 70587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int out_secondary_arch = -1; 70687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_secondary_compatibility_attr.isInitialized()) 70787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_secondary_arch = decode_secondary_compatibility_attribute( 70837b74a387bb3993387029859c2d9d051c41c724eStephen Hines out_secondary_compatibility_attr); 70987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 71087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_CurrentCPUArch = calculate_cpu_arch(out_cpu_arch, out_secondary_arch); 71187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 71287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 71387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_CPUArch >= 0) { 71487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_cpu_arch_attr.isInitialized() && "CPU arch has never set!"); 71587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(m_CurrentCPUArch >= 0); 71687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 71787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int in_cpu_arch = calculate_cpu_arch(m_CPUArch, m_SecondaryCPUArch); 71887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int result_cpu_arch = merge_cpu_arch(m_CurrentCPUArch, in_cpu_arch); 71987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 72087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (result_cpu_arch < 0) { 72137b74a387bb3993387029859c2d9d051c41c724eStephen Hines warning(diag::warn_mismatch_cpu_arch_profile) << in_cpu_arch 72237b74a387bb3993387029859c2d9d051c41c724eStephen Hines << pInput.name(); 72387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 72487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (result_cpu_arch != m_CurrentCPUArch) { 72587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Value of Tag_CPU_arch are going to changea. 72687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_CurrentCPUArch = result_cpu_arch; 72787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 72887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Write the result value to the output. 72987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (result_cpu_arch == CPU_Arch_ARM_V4T_Plus_V6_M) { 73087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_arch_attr.setIntValue(CPU_Arch_ARM_V4T); 73187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines encode_secondary_compatibility_attribute( 73287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_secondary_compatibility_attr, CPU_Arch_ARM_V6_M); 73387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 73487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_arch_attr.setIntValue(result_cpu_arch); 73587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines encode_secondary_compatibility_attribute( 73687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_secondary_compatibility_attr, -1); 73787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 73887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 73937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_cpu_name = m_Attrs[Tag_CPU_name]; 74037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_cpu_raw_name = m_Attrs[Tag_CPU_raw_name]; 74187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 74287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_CurrentCPUArch != in_cpu_arch) { 74387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Unable to guess the Tag_CPU_name. Use the generic name. 74487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_cpu_name.isInitialized()) { 74587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_name.setStringValue(get_generic_cpu_name(m_CurrentCPUArch)); 74687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 74787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 74887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_CPU_raw_name becomes unknown. Set to default value to disable 74987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // it. 75087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_raw_name.setStringValue(""); 75187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 75287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Use the value of Tag_CPU_name and Tag_CPU_raw_name from the input. 75387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_CPUName.empty()) { 75437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_cpu_name = m_Attrs[Tag_CPU_name]; 75587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_cpu_name.isInitialized() && "CPU name has never set!"); 75687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_name.setStringValue(m_CPUName); 75787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 75887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 75987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_CPURawName.empty()) { 76037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_cpu_raw_name = m_Attrs[Tag_CPU_raw_name]; 76187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_cpu_raw_name.isInitialized() && 76287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines "CPU raw name has never set!"); 76387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_raw_name.setStringValue(m_CPURawName); 76487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 76837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // (m_CPUArch >= 0) 76987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Process Tag_ABI_VFP_args. 77187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_VFPArgs >= 0) { 77237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_attr = m_Attrs[Tag_ABI_VFP_args]; 77337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_float_number_model_attr = 77487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_Attrs[Tag_ABI_FP_number_model]; 77587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_attr.isInitialized() && "VFP args has never set!"); 77787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 77887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // If the output is not permitted to use floating number, this attribute 77987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // is ignored (migrate the value from input directly.) 78087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_float_number_model_attr.isUninitialized() || 78187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (out_float_number_model_attr.getIntValue() == 0)) { 78287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Inherit requirement from input. 78387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_attr.setIntValue(m_VFPArgs); 78487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 78587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pConfig.options().warnMismatch()) 78687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines warning(diag::warn_mismatch_vfp_args) << pInput.name(); 78787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 78887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 78987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 79087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Process Tag_FP_arch. 79137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_fp_arch_attr = m_Attrs[Tag_FP_arch]; 79287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_FPArch >= 0) { 79387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_fp_arch_attr.isInitialized() && "FP arch has never set!"); 79487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 79587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_FP_arch 79687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 0: instructions requiring FP hardware are not permitted 79787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 1: VFP1 79887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 2: VFP2 79987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 3: VFP3 D32 80087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 4: VFP3 D16 80187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 5: VFP4 D32 80287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 6: VFP4 D16 80387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 7: ARM v8-A D32 80487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 8: ARM v8-A D16 80587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_fp_arch_attr.getIntValue() == 0) { 80687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Output has no constraints on FP hardware. Copy the requirement from 80787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // input. 80887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_fp_arch_attr.setIntValue(m_FPArch); 80987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (m_FPArch == 0) { 81087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Input has no constraints on FP hardware. Do nothing. 81187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 81287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // If here, both output and input contain non-zero value of Tag_FP_arch. 81387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 81487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Version greater than num_fp_configs is not defined. Choose the greater 81587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // one for future-proofing. 81687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (static_cast<unsigned>(m_FPArch) > num_fp_configs) { 81787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (static_cast<unsigned>(m_FPArch) > out_fp_arch_attr.getIntValue()) { 81887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_fp_arch_attr.setIntValue(m_FPArch); 81987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 82087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 82187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_fp_arch_attr.getIntValue() < num_fp_configs) { 82237b74a387bb3993387029859c2d9d051c41c724eStephen Hines const struct fp_config_data& input_fp_config = fp_configs[m_FPArch]; 82387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 82437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const struct fp_config_data& output_fp_config = 82537b74a387bb3993387029859c2d9d051c41c724eStephen Hines fp_configs[out_fp_arch_attr.getIntValue()]; 82687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 82787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const struct fp_config_data result_fp_config = { 82837b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*version*/ ((output_fp_config.version > input_fp_config.version) 82937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ? output_fp_config.version 83037b74a387bb3993387029859c2d9d051c41c724eStephen Hines : input_fp_config.version), 83137b74a387bb3993387029859c2d9d051c41c724eStephen Hines /* regs */ ((output_fp_config.regs > input_fp_config.regs) 83237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ? output_fp_config.regs 83337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : input_fp_config.regs), 83487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines }; 83587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Find the attribute value corresponding the result_fp_config 83687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_fp_arch_attr.setIntValue(get_fp_arch_of_config(result_fp_config)); 83787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 83887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 83987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 84037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // (m_FPArch >= 0) 84187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 84287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Process Tag_ABI_HardFP_use. 84337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_hardfp_use_attr = m_Attrs[Tag_ABI_HardFP_use]; 84487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 84587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_HardFPUseInitialized && out_hardfp_use_attr.isInitialized()) { 84687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_HardFPUse = out_hardfp_use_attr.getIntValue(); 84787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_HardFPUseInitialized = true; 84887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 84987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 85087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_HardFPUse >= 0) { 85187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_ABI_HardFP_use depends on the meaning of Tag_FP_arch when it's 0. 85287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_hardfp_use_attr.isInitialized() && "HardFP use has never set!"); 85387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 85487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_fp_arch_attr.isUninitialized() || 85587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines (out_fp_arch_attr.getIntValue() == 0)) { 85687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Has no constraints on FP hardware. 85787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_hardfp_use_attr.setIntValue(m_HardFPUse); 85887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 85987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Both output and input contain non-zero value of Tag_FP_arch and we have 86087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // different Tag_ABI_HaedFP_Use settings other than 0. 86187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if ((out_fp_arch_attr.getIntValue() > 0) && (m_HardFPUse > 0)) 86287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Promote to 3 (The user permitted this entity to use both SP and DP 86387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // VFP instruction.) 86487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_hardfp_use_attr.setIntValue(3); 86587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 86687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 86787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 86887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Move the value of Tag_MPextension_use_legacy to Tag_MPextension_use. 86937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_mpextension_use_legacy = 87087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_Attrs[Tag_MPextension_use_legacy]; 87187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 87237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_mpextension_use = m_Attrs[Tag_MPextension_use]; 87387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 87487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // If Tag_MPextension_use_legacy has value, it must be introduced by current 87587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // input since it is reset every time after the merge completed. 87687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_mpextension_use_legacy.isInitialized()) { 87787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_mpextension_use.isInitialized()) { 87887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_MPextensionUse < 0) { 87987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // The value of Tag_MPextension_use is introduced by the current input. 88087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Check whether it is consistent with the one set in legacy. 88187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_MPextensionUse = out_mpextension_use.getIntValue(); 88287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 88387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Current input introduces value of Tag_MPextension_use in 88487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // m_MPextensionUse. 88587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 88687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 88787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Check the consistency between m_MPextensionUse and the value of 88887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_MPextension_use_legacy. 88987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (static_cast<unsigned>(m_MPextensionUse) != 89037b74a387bb3993387029859c2d9d051c41c724eStephen Hines out_mpextension_use_legacy.getIntValue()) { 89187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines error(diag::error_mismatch_mpextension_use) << pInput.name(); 89287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return false; 89387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 89487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 89587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_MPextensionUse < 0) { 89687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_MPextension_use is not set. Initialize it and move the value. 89787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_mpextension_use.setType(ELFAttributeValue::Int); 89887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_mpextension_use.setIntValue(out_mpextension_use.getIntValue()); 89987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 90087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Unreachable case since the value to unitialized attribute is directly 90187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // assigned in ELFAttribute::Subsection::merge(). 90287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(false && "Tag_MPextension_use is uninitialized but have value?"); 90387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 90487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 90587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 90687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Reset the attribute to uninitialized so it won't be included in the 90787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // output. 90887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_mpextension_use_legacy.setType(ELFAttributeValue::Uninitialized); 90987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 91087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 91187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Process Tag_MPextension_use. 91287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_MPextensionUse > 0) { 91387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_mpextension_use.isInitialized()); 91487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 91587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (static_cast<unsigned>(m_MPextensionUse) > 91637b74a387bb3993387029859c2d9d051c41c724eStephen Hines out_mpextension_use.getIntValue()) { 91787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_mpextension_use.setIntValue(m_MPextensionUse); 91887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 91987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 92087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 92187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Process Tag_DIV_use. 92237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ELFAttributeValue& out_div_use_attr = m_Attrs[Tag_DIV_use]; 92387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 92487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_DIVUseInitialized && out_div_use_attr.isInitialized()) { 92587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Perform the merge by reverting value of Tag_DIV_use and setup m_DIVUse. 92687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_DIVUse = out_div_use_attr.getIntValue(); 92787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_div_use_attr.setIntValue(0); 92887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_DIVUseInitialized = true; 92987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 93087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 93187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_DIVUse >= 0) { 93287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(out_div_use_attr.isInitialized()); 93387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 93437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& out_cpu_arch_profile_attr = 93587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_Attrs[Tag_CPU_arch_profile]; 93687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 93787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int out_cpu_arch_profile = Arch_Profile_None; 93887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_cpu_arch_profile_attr.isInitialized()) { 93987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_cpu_arch_profile = out_cpu_arch_profile_attr.getIntValue(); 94087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 94187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 94287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_DIVUse == 1) { 94387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Input (=1) was not permitted to use SDIV and UDIV. See whether current 94487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // output was explicitly permitted the use. 94537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!is_allowed_use_of_div(m_CurrentCPUArch, 94637b74a387bb3993387029859c2d9d051c41c724eStephen Hines out_cpu_arch_profile, 94787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_div_use_attr.getIntValue())) { 94887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_div_use_attr.setIntValue(1); 94987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 95087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 95187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (out_div_use_attr.getIntValue() != 1) { 95287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Output does not explicitly forbid the use of SDIV/UDIV. See whether 95387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // the input attribute can allow it under current CPU architecture 95487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // profile. 95537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (is_allowed_use_of_div( 95637b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_CurrentCPUArch, out_cpu_arch_profile, m_DIVUse)) { 95787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines out_div_use_attr.setIntValue(m_DIVUse); 95887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 95987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 96087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 96187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 96287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return true; 96487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 96587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinessize_t ARMELFAttributeData::sizeOutput() const { 96787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines size_t result = 0; 96887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 96987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Size contributed by known attributes 97087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (unsigned i = 0; i <= Tag_Max; ++i) { 97187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines TagType tag = static_cast<TagType>(i); 97237b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& value = m_Attrs[tag]; 97387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 97487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (value.shouldEmit()) { 97587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines result += leb128::size(static_cast<uint32_t>(tag)); 97687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines result += value.getSize(); 97787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 97887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 97987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 98087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Size contributed by unknown attributes 98187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (UnknownAttrsMap::const_iterator unknown_attr_it = m_UnknownAttrs.begin(), 98237b74a387bb3993387029859c2d9d051c41c724eStephen Hines unknown_attr_end = m_UnknownAttrs.end(); 98337b74a387bb3993387029859c2d9d051c41c724eStephen Hines unknown_attr_it != unknown_attr_end; 98437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++unknown_attr_it) { 98587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines TagType tag = unknown_attr_it->first; 98637b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& value = unknown_attr_it->second; 98787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 98887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (value.shouldEmit()) { 98987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines result += leb128::size(static_cast<uint32_t>(tag)); 99087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines result += value.getSize(); 99187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 99287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 99387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 99487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return result; 99587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 99687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 99737b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t ARMELFAttributeData::emit(char* pBuf) const { 99837b74a387bb3993387029859c2d9d051c41c724eStephen Hines char* buffer = pBuf; 99987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 100087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_conformance "should be emitted first in a file-scope sub-subsection of 100187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // the first public subsection of the attribute section." 100287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 100387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // See ARM [ABI-addenda], 2.3.7.4 Conformance tag 100437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& attr_conformance = m_Attrs[Tag_conformance]; 100587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 100687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (attr_conformance.shouldEmit()) { 100737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!ELFAttributeData::WriteAttribute( 100837b74a387bb3993387029859c2d9d051c41c724eStephen Hines Tag_conformance, attr_conformance, buffer)) { 100987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0; 101087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 101187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 101287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 101387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_nodefaults "should be emitted before any other tag in an attribute 101487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // subsection other that the conformance tag" 101587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // 101687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // See ARM [ABI-addenda], 2.3.7.5 No defaults tag 101737b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& attr_nodefaults = m_Attrs[Tag_nodefaults]; 101887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 101987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (attr_nodefaults.shouldEmit()) { 102037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!ELFAttributeData::WriteAttribute( 102137b74a387bb3993387029859c2d9d051c41c724eStephen Hines Tag_nodefaults, attr_nodefaults, buffer)) { 102287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0; 102387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 102487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 102587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 102687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_conformance (=67) 102787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Tag_nodefaults (=64) 102887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (unsigned i = 0; i < Tag_nodefaults; ++i) { 102987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines TagType tag = static_cast<TagType>(i); 103037b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& value = m_Attrs[tag]; 103187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 103287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (value.shouldEmit() && 103387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines !ELFAttributeData::WriteAttribute(tag, value, buffer)) { 103487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0; 103587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 103687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 103787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 103887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (unsigned i = (Tag_nodefaults + 1); i <= Tag_Max; ++i) { 103987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines TagType tag = static_cast<TagType>(i); 104037b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& value = m_Attrs[tag]; 104187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 104287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (value.shouldEmit() && (i != Tag_conformance) && 104387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines !ELFAttributeData::WriteAttribute(tag, value, buffer)) { 104487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0; 104587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 104687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 104787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 104887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (UnknownAttrsMap::const_iterator unknown_attr_it = m_UnknownAttrs.begin(), 104937b74a387bb3993387029859c2d9d051c41c724eStephen Hines unknown_attr_end = m_UnknownAttrs.end(); 105037b74a387bb3993387029859c2d9d051c41c724eStephen Hines unknown_attr_it != unknown_attr_end; 105137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++unknown_attr_it) { 105287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines TagType tag = unknown_attr_it->first; 105337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const ELFAttributeValue& value = unknown_attr_it->second; 105487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 105587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (value.shouldEmit() && 105687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines !ELFAttributeData::WriteAttribute(tag, value, buffer)) { 105787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0; 105887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 105987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 106087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 106187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return (buffer - pBuf); 106287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 10630dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 106437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMELFAttributeData::usingThumb() const { 10650dea6bc96bb52346737966839ac68644f7939f58Stephen Hines int arch = m_Attrs[Tag_CPU_arch].getIntValue(); 10660dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if ((arch == CPU_Arch_ARM_V6_M) || (arch == CPU_Arch_ARM_V6S_M)) 10670dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return true; 10680dea6bc96bb52346737966839ac68644f7939f58Stephen Hines if ((arch != CPU_Arch_ARM_V7) && (arch != CPU_Arch_ARM_V7E_M)) 10690dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return false; 10700dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 10710dea6bc96bb52346737966839ac68644f7939f58Stephen Hines arch = m_Attrs[Tag_CPU_arch_profile].getIntValue(); 10720dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return arch == Arch_Profile_Microcontroller; 10730dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 10740dea6bc96bb52346737966839ac68644f7939f58Stephen Hines 107537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMELFAttributeData::usingThumb2() const { 10760dea6bc96bb52346737966839ac68644f7939f58Stephen Hines int arch = m_Attrs[Tag_CPU_arch].getIntValue(); 10770dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return (arch == CPU_Arch_ARM_V6T2) || (arch == CPU_Arch_ARM_V7); 10780dea6bc96bb52346737966839ac68644f7939f58Stephen Hines} 107937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 108037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 1081