bool testBuildAttr(unsigned Tag, unsigned Value, unsigned ExpectedTag, unsigned ExpectedValue) { std::string buffer; raw_string_ostream OS(buffer); AttributeSection Section(Tag, Value); Section.write(OS); ArrayRef<uint8_t> Bytes( reinterpret_cast<const uint8_t*>(OS.str().c_str()), OS.str().size()); ARMAttributeParser Parser; Parser.Parse(Bytes, true); return (Parser.hasAttribute(ExpectedTag) && Parser.getAttributeValue(ExpectedTag) == ExpectedValue); }
// FIXME Encode from a tablegen description or target parser. void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { if (TheTriple.getSubArch() != Triple::NoSubArch) return; ARMAttributeParser Attributes; std::error_code EC = getBuildAttributes(Attributes); if (EC) return; std::string Triple; // Default to ARM, but use the triple if it's been set. if (TheTriple.getArch() == Triple::thumb || TheTriple.getArch() == Triple::thumbeb) Triple = "thumb"; else Triple = "arm"; if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) { switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) { case ARMBuildAttrs::v4: Triple += "v4"; break; case ARMBuildAttrs::v4T: Triple += "v4t"; break; case ARMBuildAttrs::v5T: Triple += "v5t"; break; case ARMBuildAttrs::v5TE: Triple += "v5te"; break; case ARMBuildAttrs::v5TEJ: Triple += "v5tej"; break; case ARMBuildAttrs::v6: Triple += "v6"; break; case ARMBuildAttrs::v6KZ: Triple += "v6kz"; break; case ARMBuildAttrs::v6T2: Triple += "v6t2"; break; case ARMBuildAttrs::v6K: Triple += "v6k"; break; case ARMBuildAttrs::v7: Triple += "v7"; break; case ARMBuildAttrs::v6_M: Triple += "v6m"; break; case ARMBuildAttrs::v6S_M: Triple += "v6sm"; break; case ARMBuildAttrs::v7E_M: Triple += "v7em"; break; } } if (!isLittleEndian()) Triple += "eb"; TheTriple.setArchName(Triple); }
SubtargetFeatures ELFObjectFileBase::getARMFeatures() const { SubtargetFeatures Features; ARMAttributeParser Attributes; std::error_code EC = getBuildAttributes(Attributes); if (EC) return SubtargetFeatures(); // both ARMv7-M and R have to support thumb hardware div bool isV7 = false; if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch) == ARMBuildAttrs::v7; if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) { switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) { case ARMBuildAttrs::ApplicationProfile: Features.AddFeature("aclass"); break; case ARMBuildAttrs::RealTimeProfile: Features.AddFeature("rclass"); if (isV7) Features.AddFeature("hwdiv"); break; case ARMBuildAttrs::MicroControllerProfile: Features.AddFeature("mclass"); if (isV7) Features.AddFeature("hwdiv"); break; } } if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) { switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) { default: break; case ARMBuildAttrs::Not_Allowed: Features.AddFeature("thumb", false); Features.AddFeature("thumb2", false); break; case ARMBuildAttrs::AllowThumb32: Features.AddFeature("thumb2"); break; } } if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) { switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) { default: break; case ARMBuildAttrs::Not_Allowed: Features.AddFeature("vfp2", false); Features.AddFeature("vfp3", false); Features.AddFeature("vfp4", false); break; case ARMBuildAttrs::AllowFPv2: Features.AddFeature("vfp2"); break; case ARMBuildAttrs::AllowFPv3A: case ARMBuildAttrs::AllowFPv3B: Features.AddFeature("vfp3"); break; case ARMBuildAttrs::AllowFPv4A: case ARMBuildAttrs::AllowFPv4B: Features.AddFeature("vfp4"); break; } } if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) { switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) { default: break; case ARMBuildAttrs::Not_Allowed: Features.AddFeature("neon", false); Features.AddFeature("fp16", false); break; case ARMBuildAttrs::AllowNeon: Features.AddFeature("neon"); break; case ARMBuildAttrs::AllowNeon2: Features.AddFeature("neon"); Features.AddFeature("fp16"); break; } } if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) { switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) { default: break; case ARMBuildAttrs::DisallowDIV: Features.AddFeature("hwdiv", false); Features.AddFeature("hwdiv-arm", false); break; case ARMBuildAttrs::AllowDIVExt: Features.AddFeature("hwdiv"); Features.AddFeature("hwdiv-arm"); break; } } return Features; }