Home | History | Annotate | Line # | Download | only in Support
      1 //===- ARMAttributeParser.cpp - ARM Attribute Information Printer ---------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #include "llvm/Support/ARMAttributeParser.h"
     10 #include "llvm/ADT/STLExtras.h"
     11 #include "llvm/ADT/StringExtras.h"
     12 #include "llvm/Support/Errc.h"
     13 #include "llvm/Support/LEB128.h"
     14 #include "llvm/Support/ScopedPrinter.h"
     15 
     16 using namespace llvm;
     17 using namespace llvm::ARMBuildAttrs;
     18 
     19 #define ATTRIBUTE_HANDLER(attr)                                                \
     20   { ARMBuildAttrs::attr, &ARMAttributeParser::attr }
     21 
     22 const ARMAttributeParser::DisplayHandler ARMAttributeParser::displayRoutines[] =
     23     {
     24         {ARMBuildAttrs::CPU_raw_name, &ARMAttributeParser::stringAttribute},
     25         {ARMBuildAttrs::CPU_name, &ARMAttributeParser::stringAttribute},
     26         ATTRIBUTE_HANDLER(CPU_arch),
     27         ATTRIBUTE_HANDLER(CPU_arch_profile),
     28         ATTRIBUTE_HANDLER(ARM_ISA_use),
     29         ATTRIBUTE_HANDLER(THUMB_ISA_use),
     30         ATTRIBUTE_HANDLER(FP_arch),
     31         ATTRIBUTE_HANDLER(WMMX_arch),
     32         ATTRIBUTE_HANDLER(Advanced_SIMD_arch),
     33         ATTRIBUTE_HANDLER(MVE_arch),
     34         ATTRIBUTE_HANDLER(PCS_config),
     35         ATTRIBUTE_HANDLER(ABI_PCS_R9_use),
     36         ATTRIBUTE_HANDLER(ABI_PCS_RW_data),
     37         ATTRIBUTE_HANDLER(ABI_PCS_RO_data),
     38         ATTRIBUTE_HANDLER(ABI_PCS_GOT_use),
     39         ATTRIBUTE_HANDLER(ABI_PCS_wchar_t),
     40         ATTRIBUTE_HANDLER(ABI_FP_rounding),
     41         ATTRIBUTE_HANDLER(ABI_FP_denormal),
     42         ATTRIBUTE_HANDLER(ABI_FP_exceptions),
     43         ATTRIBUTE_HANDLER(ABI_FP_user_exceptions),
     44         ATTRIBUTE_HANDLER(ABI_FP_number_model),
     45         ATTRIBUTE_HANDLER(ABI_align_needed),
     46         ATTRIBUTE_HANDLER(ABI_align_preserved),
     47         ATTRIBUTE_HANDLER(ABI_enum_size),
     48         ATTRIBUTE_HANDLER(ABI_HardFP_use),
     49         ATTRIBUTE_HANDLER(ABI_VFP_args),
     50         ATTRIBUTE_HANDLER(ABI_WMMX_args),
     51         ATTRIBUTE_HANDLER(ABI_optimization_goals),
     52         ATTRIBUTE_HANDLER(ABI_FP_optimization_goals),
     53         ATTRIBUTE_HANDLER(compatibility),
     54         ATTRIBUTE_HANDLER(CPU_unaligned_access),
     55         ATTRIBUTE_HANDLER(FP_HP_extension),
     56         ATTRIBUTE_HANDLER(ABI_FP_16bit_format),
     57         ATTRIBUTE_HANDLER(MPextension_use),
     58         ATTRIBUTE_HANDLER(DIV_use),
     59         ATTRIBUTE_HANDLER(DSP_extension),
     60         ATTRIBUTE_HANDLER(T2EE_use),
     61         ATTRIBUTE_HANDLER(Virtualization_use),
     62         ATTRIBUTE_HANDLER(nodefaults),
     63 };
     64 
     65 #undef ATTRIBUTE_HANDLER
     66 
     67 Error ARMAttributeParser::stringAttribute(AttrType tag) {
     68   StringRef tagName =
     69       ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*TagPrefix=*/false);
     70   StringRef desc = de.getCStrRef(cursor);
     71 
     72   if (sw) {
     73     DictScope scope(*sw, "Attribute");
     74     sw->printNumber("Tag", tag);
     75     if (!tagName.empty())
     76       sw->printString("TagName", tagName);
     77     sw->printString("Value", desc);
     78   }
     79   return Error::success();
     80 }
     81 
     82 Error ARMAttributeParser::CPU_arch(AttrType tag) {
     83   static const char *strings[] = {
     84     "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ", "ARM v6",
     85     "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M", "ARM v6S-M",
     86     "ARM v7E-M", "ARM v8", nullptr,
     87     "ARM v8-M Baseline", "ARM v8-M Mainline", nullptr, nullptr, nullptr,
     88     "ARM v8.1-M Mainline"
     89   };
     90   return parseStringAttribute("CPU_arch", tag, makeArrayRef(strings));
     91 }
     92 
     93 Error ARMAttributeParser::CPU_arch_profile(AttrType tag) {
     94   uint64_t value = de.getULEB128(cursor);
     95 
     96   StringRef profile;
     97   switch (value) {
     98   default: profile = "Unknown"; break;
     99   case 'A': profile = "Application"; break;
    100   case 'R': profile = "Real-time"; break;
    101   case 'M': profile = "Microcontroller"; break;
    102   case 'S': profile = "Classic"; break;
    103   case 0: profile = "None"; break;
    104   }
    105 
    106   printAttribute(tag, value, profile);
    107   return Error::success();
    108 }
    109 
    110 Error ARMAttributeParser::ARM_ISA_use(AttrType tag) {
    111   static const char *strings[] = {"Not Permitted", "Permitted"};
    112   return parseStringAttribute("ARM_ISA_use", tag, makeArrayRef(strings));
    113 }
    114 
    115 Error ARMAttributeParser::THUMB_ISA_use(AttrType tag) {
    116   static const char *strings[] = {"Not Permitted", "Thumb-1", "Thumb-2", "Permitted"};
    117   return parseStringAttribute("THUMB_ISA_use", tag, makeArrayRef(strings));
    118 }
    119 
    120 Error ARMAttributeParser::FP_arch(AttrType tag) {
    121   static const char *strings[] = {
    122       "Not Permitted", "VFPv1",     "VFPv2",      "VFPv3",         "VFPv3-D16",
    123       "VFPv4",         "VFPv4-D16", "ARMv8-a FP", "ARMv8-a FP-D16"};
    124   return parseStringAttribute("FP_arch", tag, makeArrayRef(strings));
    125 }
    126 
    127 Error ARMAttributeParser::WMMX_arch(AttrType tag) {
    128   static const char *strings[] = {"Not Permitted", "WMMXv1", "WMMXv2"};
    129   return parseStringAttribute("WMMX_arch", tag, makeArrayRef(strings));
    130 }
    131 
    132 Error ARMAttributeParser::Advanced_SIMD_arch(AttrType tag) {
    133   static const char *strings[] = {"Not Permitted", "NEONv1", "NEONv2+FMA",
    134                                   "ARMv8-a NEON", "ARMv8.1-a NEON"};
    135   return parseStringAttribute("Advanced_SIMD_arch", tag, makeArrayRef(strings));
    136 }
    137 
    138 Error ARMAttributeParser::MVE_arch(AttrType tag) {
    139   static const char *strings[] = {"Not Permitted", "MVE integer",
    140                                   "MVE integer and float"};
    141   return parseStringAttribute("MVE_arch", tag, makeArrayRef(strings));
    142 }
    143 
    144 Error ARMAttributeParser::PCS_config(AttrType tag) {
    145   static const char *strings[] = {
    146     "None", "Bare Platform", "Linux Application", "Linux DSO", "Palm OS 2004",
    147     "Reserved (Palm OS)", "Symbian OS 2004", "Reserved (Symbian OS)"};
    148   return parseStringAttribute("PCS_config", tag, makeArrayRef(strings));
    149 }
    150 
    151 Error ARMAttributeParser::ABI_PCS_R9_use(AttrType tag) {
    152   static const char *strings[] = {"v6", "Static Base", "TLS", "Unused"};
    153   return parseStringAttribute("ABI_PCS_R9_use", tag, makeArrayRef(strings));
    154 }
    155 
    156 Error ARMAttributeParser::ABI_PCS_RW_data(AttrType tag) {
    157   static const char *strings[] = {"Absolute", "PC-relative", "SB-relative",
    158                                   "Not Permitted"};
    159   return parseStringAttribute("ABI_PCS_RW_data", tag, makeArrayRef(strings));
    160 }
    161 
    162 Error ARMAttributeParser::ABI_PCS_RO_data(AttrType tag) {
    163   static const char *strings[] = {"Absolute", "PC-relative", "Not Permitted"};
    164   return parseStringAttribute("ABI_PCS_RO_data", tag, makeArrayRef(strings));
    165 }
    166 
    167 Error ARMAttributeParser::ABI_PCS_GOT_use(AttrType tag) {
    168   static const char *strings[] = {"Not Permitted", "Direct", "GOT-Indirect"};
    169   return parseStringAttribute("ABI_PCS_GOT_use", tag, makeArrayRef(strings));
    170 }
    171 
    172 Error ARMAttributeParser::ABI_PCS_wchar_t(AttrType tag) {
    173   static const char *strings[] = {"Not Permitted", "Unknown", "2-byte",
    174                                   "Unknown", "4-byte"};
    175   return parseStringAttribute("ABI_PCS_wchar_t", tag, makeArrayRef(strings));
    176 }
    177 
    178 Error ARMAttributeParser::ABI_FP_rounding(AttrType tag) {
    179   static const char *strings[] = {"IEEE-754", "Runtime"};
    180   return parseStringAttribute("ABI_FP_rounding", tag, makeArrayRef(strings));
    181 }
    182 
    183 Error ARMAttributeParser::ABI_FP_denormal(AttrType tag) {
    184   static const char *strings[] = {"Unsupported", "IEEE-754", "Sign Only"};
    185   return parseStringAttribute("ABI_FP_denormal", tag, makeArrayRef(strings));
    186 }
    187 
    188 Error ARMAttributeParser::ABI_FP_exceptions(AttrType tag) {
    189   static const char *strings[] = {"Not Permitted", "IEEE-754"};
    190   return parseStringAttribute("ABI_FP_exceptions", tag, makeArrayRef(strings));
    191 }
    192 Error ARMAttributeParser::ABI_FP_user_exceptions(AttrType tag) {
    193   static const char *strings[] = {"Not Permitted", "IEEE-754"};
    194   return parseStringAttribute("ABI_FP_user_exceptions", tag,
    195                               makeArrayRef(strings));
    196 }
    197 
    198 Error ARMAttributeParser::ABI_FP_number_model(AttrType tag) {
    199   static const char *strings[] = {"Not Permitted", "Finite Only", "RTABI",
    200                                   "IEEE-754"};
    201   return parseStringAttribute("ABI_FP_number_model", tag,
    202                               makeArrayRef(strings));
    203 }
    204 
    205 Error ARMAttributeParser::ABI_align_needed(AttrType tag) {
    206   static const char *strings[] = {"Not Permitted", "8-byte alignment",
    207                                   "4-byte alignment", "Reserved"};
    208 
    209   uint64_t value = de.getULEB128(cursor);
    210 
    211   std::string description;
    212   if (value < array_lengthof(strings))
    213     description = strings[value];
    214   else if (value <= 12)
    215     description = "8-byte alignment, " + utostr(1ULL << value) +
    216                   "-byte extended alignment";
    217   else
    218     description = "Invalid";
    219 
    220   printAttribute(tag, value, description);
    221   return Error::success();
    222 }
    223 
    224 Error ARMAttributeParser::ABI_align_preserved(AttrType tag) {
    225   static const char *strings[] = {"Not Required", "8-byte data alignment",
    226                                   "8-byte data and code alignment", "Reserved"};
    227 
    228   uint64_t value = de.getULEB128(cursor);
    229 
    230   std::string description;
    231   if (value < array_lengthof(strings))
    232     description = std::string(strings[value]);
    233   else if (value <= 12)
    234     description = std::string("8-byte stack alignment, ") +
    235                   utostr(1ULL << value) + std::string("-byte data alignment");
    236   else
    237     description = "Invalid";
    238 
    239   printAttribute(tag, value, description);
    240   return Error::success();
    241 }
    242 
    243 Error ARMAttributeParser::ABI_enum_size(AttrType tag) {
    244   static const char *strings[] = {"Not Permitted", "Packed", "Int32",
    245                                   "External Int32"};
    246   return parseStringAttribute("ABI_enum_size", tag, makeArrayRef(strings));
    247 }
    248 
    249 Error ARMAttributeParser::ABI_HardFP_use(AttrType tag) {
    250   static const char *strings[] = {"Tag_FP_arch", "Single-Precision", "Reserved",
    251                                   "Tag_FP_arch (deprecated)"};
    252   return parseStringAttribute("ABI_HardFP_use", tag, makeArrayRef(strings));
    253 }
    254 
    255 Error ARMAttributeParser::ABI_VFP_args(AttrType tag) {
    256   static const char *strings[] = {"AAPCS", "AAPCS VFP", "Custom",
    257                                   "Not Permitted"};
    258   return parseStringAttribute("ABI_VFP_args", tag, makeArrayRef(strings));
    259 }
    260 
    261 Error ARMAttributeParser::ABI_WMMX_args(AttrType tag) {
    262   static const char *strings[] = {"AAPCS", "iWMMX", "Custom"};
    263   return parseStringAttribute("ABI_WMMX_args", tag, makeArrayRef(strings));
    264 }
    265 
    266 Error ARMAttributeParser::ABI_optimization_goals(AttrType tag) {
    267   static const char *strings[] = {
    268     "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Debugging",
    269     "Best Debugging"
    270   };
    271   return parseStringAttribute("ABI_optimization_goals", tag,
    272                               makeArrayRef(strings));
    273 }
    274 
    275 Error ARMAttributeParser::ABI_FP_optimization_goals(AttrType tag) {
    276   static const char *strings[] = {
    277       "None",     "Speed",        "Aggressive Speed", "Size", "Aggressive Size",
    278       "Accuracy", "Best Accuracy"};
    279   return parseStringAttribute("ABI_FP_optimization_goals", tag,
    280                               makeArrayRef(strings));
    281 }
    282 
    283 Error ARMAttributeParser::compatibility(AttrType tag) {
    284   uint64_t integer = de.getULEB128(cursor);
    285   StringRef string = de.getCStrRef(cursor);
    286 
    287   if (sw) {
    288     DictScope scope(*sw, "Attribute");
    289     sw->printNumber("Tag", tag);
    290     sw->startLine() << "Value: " << integer << ", " << string << '\n';
    291     sw->printString("TagName",
    292                     ELFAttrs::attrTypeAsString(tag, tagToStringMap,
    293                                                /*hasTagPrefix=*/false));
    294     switch (integer) {
    295     case 0:
    296       sw->printString("Description", StringRef("No Specific Requirements"));
    297       break;
    298     case 1:
    299       sw->printString("Description", StringRef("AEABI Conformant"));
    300       break;
    301     default:
    302       sw->printString("Description", StringRef("AEABI Non-Conformant"));
    303       break;
    304     }
    305   }
    306   return Error::success();
    307 }
    308 
    309 Error ARMAttributeParser::CPU_unaligned_access(AttrType tag) {
    310   static const char *strings[] = {"Not Permitted", "v6-style"};
    311   return parseStringAttribute("CPU_unaligned_access", tag,
    312                               makeArrayRef(strings));
    313 }
    314 
    315 Error ARMAttributeParser::FP_HP_extension(AttrType tag) {
    316   static const char *strings[] = {"If Available", "Permitted"};
    317   return parseStringAttribute("FP_HP_extension", tag, makeArrayRef(strings));
    318 }
    319 
    320 Error ARMAttributeParser::ABI_FP_16bit_format(AttrType tag) {
    321   static const char *strings[] = {"Not Permitted", "IEEE-754", "VFPv3"};
    322   return parseStringAttribute("ABI_FP_16bit_format", tag,
    323                               makeArrayRef(strings));
    324 }
    325 
    326 Error ARMAttributeParser::MPextension_use(AttrType tag) {
    327   static const char *strings[] = {"Not Permitted", "Permitted"};
    328   return parseStringAttribute("MPextension_use", tag, makeArrayRef(strings));
    329 }
    330 
    331 Error ARMAttributeParser::DIV_use(AttrType tag) {
    332   static const char *strings[] = {"If Available", "Not Permitted", "Permitted"};
    333   return parseStringAttribute("DIV_use", tag, makeArrayRef(strings));
    334 }
    335 
    336 Error ARMAttributeParser::DSP_extension(AttrType tag) {
    337   static const char *strings[] = {"Not Permitted", "Permitted"};
    338   return parseStringAttribute("DSP_extension", tag, makeArrayRef(strings));
    339 }
    340 
    341 Error ARMAttributeParser::T2EE_use(AttrType tag) {
    342   static const char *strings[] = {"Not Permitted", "Permitted"};
    343   return parseStringAttribute("T2EE_use", tag, makeArrayRef(strings));
    344 }
    345 
    346 Error ARMAttributeParser::Virtualization_use(AttrType tag) {
    347   static const char *strings[] = {"Not Permitted", "TrustZone",
    348                                   "Virtualization Extensions",
    349                                   "TrustZone + Virtualization Extensions"};
    350   return parseStringAttribute("Virtualization_use", tag, makeArrayRef(strings));
    351 }
    352 
    353 Error ARMAttributeParser::nodefaults(AttrType tag) {
    354   uint64_t value = de.getULEB128(cursor);
    355   printAttribute(tag, value, "Unspecified Tags UNDEFINED");
    356   return Error::success();
    357 }
    358 
    359 Error ARMAttributeParser::handler(uint64_t tag, bool &handled) {
    360   handled = false;
    361   for (unsigned AHI = 0, AHE = array_lengthof(displayRoutines); AHI != AHE;
    362        ++AHI) {
    363     if (uint64_t(displayRoutines[AHI].attribute) == tag) {
    364       if (Error e =
    365               (this->*displayRoutines[AHI].routine)(static_cast<AttrType>(tag)))
    366         return e;
    367       handled = true;
    368       break;
    369     }
    370   }
    371 
    372   return Error::success();
    373 }
    374