<commit_before>//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format ARM assembly language.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "asm-printer"
#include "ARM.h"
#include "ARMAsmPrinter.h"
#include "ARMBuildAttrs.h"
#include "ARMBaseRegisterInfo.h"
#include "ARMConstantPoolValue.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMTargetMachine.h"
#include "ARMTargetObjectFile.h"
#include "InstPrinter/ARMInstPrinter.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMMCExpr.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
using namespace llvm;

namespace {

  // Per section and per symbol attributes are not supported.
  // To implement them we would need the ability to delay this emission
  // until the assembly file is fully parsed/generated as only then do we
  // know the symbol and section numbers.
  class AttributeEmitter {
  public:
    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
    virtual void Finish() = 0;
    virtual ~AttributeEmitter() {}
  };

  class AsmAttributeEmitter : public AttributeEmitter {
    MCStreamer &Streamer;

  public:
    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
    void MaybeSwitchVendor(StringRef Vendor) { }

    void EmitAttribute(unsigned Attribute, unsigned Value) {
      Streamer.EmitRawText("\t.eabi_attribute " +
                           Twine(Attribute) + ", " + Twine(Value));
    }

    void EmitTextAttribute(unsigned Attribute, StringRef String) {
      switch (Attribute) {
      case ARMBuildAttrs::CPU_name:
        Streamer.EmitRawText(StringRef("\t.cpu ") + LowercaseString(String));
        break;
      /* GAS requires .fpu to be emitted regardless of EABI attribute */
      case ARMBuildAttrs::Advanced_SIMD_arch:
      case ARMBuildAttrs::VFP_arch:
        Streamer.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String));
        break;    
      default: assert(0 && "Unsupported Text attribute in ASM Mode"); break;
      }
    }
    void Finish() { }
  };

  class ObjectAttributeEmitter : public AttributeEmitter {
    MCObjectStreamer &Streamer;
    StringRef CurrentVendor;
    SmallString<64> Contents;

  public:
    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
      Streamer(Streamer_), CurrentVendor("") { }

    void MaybeSwitchVendor(StringRef Vendor) {
      assert(!Vendor.empty() && "Vendor cannot be empty.");

      if (CurrentVendor.empty())
        CurrentVendor = Vendor;
      else if (CurrentVendor == Vendor)
        return;
      else
        Finish();

      CurrentVendor = Vendor;

      assert(Contents.size() == 0);
    }

    void EmitAttribute(unsigned Attribute, unsigned Value) {
      // FIXME: should be ULEB
      Contents += Attribute;
      Contents += Value;
    }

    void EmitTextAttribute(unsigned Attribute, StringRef String) {
      Contents += Attribute;
      Contents += UppercaseString(String);
      Contents += 0;
    }

    void Finish() {
      const size_t ContentsSize = Contents.size();

      // Vendor size + Vendor name + '\0'
      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;

      // Tag + Tag Size
      const size_t TagHeaderSize = 1 + 4;

      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
      Streamer.EmitBytes(CurrentVendor, 0);
      Streamer.EmitIntValue(0, 1); // '\0'

      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);

      Streamer.EmitBytes(Contents, 0);

      Contents.clear();
    }
  };

} // end of anonymous namespace

MachineLocation ARMAsmPrinter::<commit_msg>Emitting ARM build attributes and values as ULEB, rather than char.<commit_after>//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format ARM assembly language.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "asm-printer"
#include "ARM.h"
#include "ARMAsmPrinter.h"
#include "ARMBuildAttrs.h"
#include "ARMBaseRegisterInfo.h"
#include "ARMConstantPoolValue.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMTargetMachine.h"
#include "ARMTargetObjectFile.h"
#include "InstPrinter/ARMInstPrinter.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMMCExpr.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
using namespace llvm;

namespace {

  // Per section and per symbol attributes are not supported.
  // To implement them we would need the ability to delay this emission
  // until the assembly file is fully parsed/generated as only then do we
  // know the symbol and section numbers.
  class AttributeEmitter {
  public:
    virtual void MaybeSwitchVendor(StringRef Vendor) = 0;
    virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0;
    virtual void EmitTextAttribute(unsigned Attribute, StringRef String) = 0;
    virtual void Finish() = 0;
    virtual ~AttributeEmitter() {}
  };

  class AsmAttributeEmitter : public AttributeEmitter {
    MCStreamer &Streamer;

  public:
    AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {}
    void MaybeSwitchVendor(StringRef Vendor) { }

    void EmitAttribute(unsigned Attribute, unsigned Value) {
      Streamer.EmitRawText("\t.eabi_attribute " +
                           Twine(Attribute) + ", " + Twine(Value));
    }

    void EmitTextAttribute(unsigned Attribute, StringRef String) {
      switch (Attribute) {
      case ARMBuildAttrs::CPU_name:
        Streamer.EmitRawText(StringRef("\t.cpu ") + LowercaseString(String));
        break;
      /* GAS requires .fpu to be emitted regardless of EABI attribute */
      case ARMBuildAttrs::Advanced_SIMD_arch:
      case ARMBuildAttrs::VFP_arch:
        Streamer.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String));
        break;    
      default: assert(0 && "Unsupported Text attribute in ASM Mode"); break;
      }
    }
    void Finish() { }
  };

  class ObjectAttributeEmitter : public AttributeEmitter {
    // This structure holds all attributes, accounting for
    // their string/numeric value, so we can later emmit them
    // in declaration order, keeping all in the same vector
    struct AttributeItemType {
      enum {
        HiddenAttribute = 0,
        NumericAttribute,
        TextAttribute
      } Type;
      unsigned Tag;
      unsigned IntValue;
      StringRef StringValue;
    } AttributeItem;

    MCObjectStreamer &Streamer;
    StringRef CurrentVendor;
    SmallVector<AttributeItemType, 64> Contents;

    // Account for the ULEB/String size of each item,
    // not just the number of items
    size_t ContentsSize;
    // FIXME: this should be in a more generic place, but
    // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
    size_t getULEBSize(int Value) {
      size_t Size = 0;
      do {
        Value >>= 7;
        Size += sizeof(int8_t); // Is this really necessary?
      } while (Value);
      return Size;
    }

  public:
    ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
      Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }

    void MaybeSwitchVendor(StringRef Vendor) {
      assert(!Vendor.empty() && "Vendor cannot be empty.");

      if (CurrentVendor.empty())
        CurrentVendor = Vendor;
      else if (CurrentVendor == Vendor)
        return;
      else
        Finish();

      CurrentVendor = Vendor;

      assert(Contents.size() == 0);
    }

    void EmitAttribute(unsigned Attribute, unsigned Value) {
      AttributeItemType attr = {
        AttributeItemType::NumericAttribute,
        Attribute,
        Value,
        StringRef("")
      };
      ContentsSize += getULEBSize(Attribute);
      ContentsSize += getULEBSize(Value);
      Contents.push_back(attr);
    }

    void EmitTextAttribute(unsigned Attribute, StringRef String) {
      AttributeItemType attr = {
        AttributeItemType::TextAttribute,
        Attribute,
        0,
        String
      };
      ContentsSize += getULEBSize(Attribute);
      // String + \0
      ContentsSize += String.size()+1;

      Contents.push_back(attr);
    }

    void Finish() {
      // Vendor size + Vendor name + '\0'
      const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;

      // Tag + Tag Size
      const size_t TagHeaderSize = 1 + 4;

      Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
      Streamer.EmitBytes(CurrentVendor, 0);
      Streamer.EmitIntValue(0, 1); // '\0'

      Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
      Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);

      // Size should have been accounted for already, now
      // emit each field as its type (ULEB or String)
      for (unsigned int i=0; i<Contents.size(); ++i) {
        AttributeItemType item = Contents[i];
        Streamer.EmitULEB128IntValue(item.Tag, 0);
        switch (item.Type) {
        case AttributeItemType::NumericAttribute:
          Streamer.EmitULEB128IntValue(item.IntValue, 0);
          break;
        case AttributeItemType::TextAttribute:
          Streamer.EmitBytes(UppercaseString(item.StringValue), 0);
          Streamer.EmitIntValue(0, 1); // '\0'
          break;
        default:
          assert(0 && "Invalid attribute type");
        }
      }

      Contents.clear();
    }
  };

} // end of anonymous namespace

MachineLocation ARMAsmPrinter::
{'fraction_non_alphanumeric': 0.13654423092516013, 'fraction_numerical': 0.005189329441336253, 'mean_word_length': 2.939316512296391, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3288530', 'n_tokens_mistral': 3780, 'n_tokens_neox': 3709, 'n_words': 914}