diff options
Diffstat (limited to 'lib/Target')
59 files changed, 0 insertions, 10746 deletions
diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp deleted file mode 100644 index bf2c14e..0000000 --- a/lib/Target/ARM/ARMTargetAsmInfo.cpp +++ /dev/null @@ -1,254 +0,0 @@ -//===-- ARMTargetAsmInfo.cpp - ARM asm properties ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the ARMTargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "ARMTargetAsmInfo.h" -#include "ARMTargetMachine.h" -#include <cstring> -#include <cctype> -using namespace llvm; - -const char *const llvm::arm_asm_table[] = { - "{r0}", "r0", - "{r1}", "r1", - "{r2}", "r2", - "{r3}", "r3", - "{r4}", "r4", - "{r5}", "r5", - "{r6}", "r6", - "{r7}", "r7", - "{r8}", "r8", - "{r9}", "r9", - "{r10}", "r10", - "{r11}", "r11", - "{r12}", "r12", - "{r13}", "r13", - "{r14}", "r14", - "{lr}", "lr", - "{sp}", "sp", - "{ip}", "ip", - "{fp}", "fp", - "{sl}", "sl", - "{memory}", "memory", - "{cc}", "cc", - 0,0 -}; - -ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM): - ARMTargetAsmInfo<DarwinTargetAsmInfo>(TM) { - Subtarget = &TM.getSubtarget<ARMSubtarget>(); - - ZeroDirective = "\t.space\t"; - ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill - SetDirective = "\t.set\t"; - ProtectedDirective = NULL; - HasDotTypeDotSizeDirective = false; - SupportsDebugInformation = true; -} - -ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM): - ARMTargetAsmInfo<ELFTargetAsmInfo>(TM) { - Subtarget = &TM.getSubtarget<ARMSubtarget>(); - - NeedsSet = false; - HasLEB128 = true; - AbsoluteDebugSectionOffsets = true; - CStringSection = ".rodata.str"; - PrivateGlobalPrefix = ".L"; - WeakRefDirective = "\t.weak\t"; - SetDirective = "\t.set\t"; - DwarfRequiresFrameSection = false; - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",%progbits"; - DwarfInfoSection = "\t.section\t.debug_info,\"\",%progbits"; - DwarfLineSection = "\t.section\t.debug_line,\"\",%progbits"; - DwarfFrameSection = "\t.section\t.debug_frame,\"\",%progbits"; - DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",%progbits"; - DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",%progbits"; - DwarfStrSection = "\t.section\t.debug_str,\"\",%progbits"; - DwarfLocSection = "\t.section\t.debug_loc,\"\",%progbits"; - DwarfARangesSection = "\t.section\t.debug_aranges,\"\",%progbits"; - DwarfRangesSection = "\t.section\t.debug_ranges,\"\",%progbits"; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",%progbits"; - - if (Subtarget->isAAPCS_ABI()) { - StaticCtorsSection = "\t.section .init_array,\"aw\",%init_array"; - StaticDtorsSection = "\t.section .fini_array,\"aw\",%fini_array"; - } else { - StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits"; - StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits"; - } - SupportsDebugInformation = true; -} - -/// Count the number of comma-separated arguments. -/// Do not try to detect errors. -template <class BaseTAI> -unsigned ARMTargetAsmInfo<BaseTAI>::countArguments(const char* p) const { - unsigned count = 0; - while (*p && isspace(*p) && *p != '\n') - p++; - count++; - while (*p && *p!='\n' && - strncmp(p, BaseTAI::CommentString, - strlen(BaseTAI::CommentString))!=0) { - if (*p==',') - count++; - p++; - } - return count; -} - -/// Count the length of a string enclosed in quote characters. -/// Do not try to detect errors. -template <class BaseTAI> -unsigned ARMTargetAsmInfo<BaseTAI>::countString(const char* p) const { - unsigned count = 0; - while (*p && isspace(*p) && *p!='\n') - p++; - if (!*p || *p != '\"') - return count; - while (*++p && *p != '\"') - count++; - return count; -} - -/// ARM-specific version of TargetAsmInfo::getInlineAsmLength. -template <class BaseTAI> -unsigned ARMTargetAsmInfo<BaseTAI>::getInlineAsmLength(const char *s) const { - // Make a lowercase-folded version of s for counting purposes. - char *q, *s_copy = (char *)malloc(strlen(s) + 1); - strcpy(s_copy, s); - for (q=s_copy; *q; q++) - *q = tolower(*q); - const char *Str = s_copy; - - // Count the number of bytes in the asm. - bool atInsnStart = true; - bool inTextSection = true; - unsigned Length = 0; - for (; *Str; ++Str) { - if (atInsnStart) { - // Skip whitespace - while (*Str && isspace(*Str) && *Str != '\n') - Str++; - // Skip label - for (const char* p = Str; *p && !isspace(*p); p++) - if (*p == ':') { - Str = p+1; - while (*Str && isspace(*Str) && *Str != '\n') - Str++; - break; - } - - if (*Str == 0) break; - - // Ignore everything from comment char(s) to EOL - if (strncmp(Str, BaseTAI::CommentString, - strlen(BaseTAI::CommentString)) == 0) - atInsnStart = false; - // FIXME do something like the following for non-Darwin - else if (*Str == '.' && Subtarget->isTargetDarwin()) { - // Directive. - atInsnStart = false; - - // Some change the section, but don't generate code. - if (strncmp(Str, ".literal4", strlen(".literal4"))==0 || - strncmp(Str, ".literal8", strlen(".literal8"))==0 || - strncmp(Str, ".const", strlen(".const"))==0 || - strncmp(Str, ".constructor", strlen(".constructor"))==0 || - strncmp(Str, ".cstring", strlen(".cstring"))==0 || - strncmp(Str, ".data", strlen(".data"))==0 || - strncmp(Str, ".destructor", strlen(".destructor"))==0 || - strncmp(Str, ".fvmlib_init0", strlen(".fvmlib_init0"))==0 || - strncmp(Str, ".fvmlib_init1", strlen(".fvmlib_init1"))==0 || - strncmp(Str, ".mod_init_func", strlen(".mod_init_func"))==0 || - strncmp(Str, ".mod_term_func", strlen(".mod_term_func"))==0 || - strncmp(Str, ".picsymbol_stub", strlen(".picsymbol_stub"))==0 || - strncmp(Str, ".symbol_stub", strlen(".symbol_stub"))==0 || - strncmp(Str, ".static_data", strlen(".static_data"))==0 || - strncmp(Str, ".section", strlen(".section"))==0 || - strncmp(Str, ".lazy_symbol_pointer", strlen(".lazy_symbol_pointer"))==0 || - strncmp(Str, ".non_lazy_symbol_pointer", strlen(".non_lazy_symbol_pointer"))==0 || - strncmp(Str, ".dyld", strlen(".dyld"))==0 || - strncmp(Str, ".const_data", strlen(".const_data"))==0 || - strncmp(Str, ".objc", strlen(".objc"))==0 || //// many directives - strncmp(Str, ".static_const", strlen(".static_const"))==0) - inTextSection=false; - else if (strncmp(Str, ".text", strlen(".text"))==0) - inTextSection = true; - // Some can't really be handled without implementing significant pieces - // of an assembler. Others require dynamic adjustment of block sizes in - // AdjustBBOffsetsAfter; it's a big compile-time speed hit to check every - // instruction in there, and none of these are currently used in the kernel. - else if (strncmp(Str, ".macro", strlen(".macro"))==0 || - strncmp(Str, ".if", strlen(".if"))==0 || - strncmp(Str, ".align", strlen(".align"))==0 || - strncmp(Str, ".fill", strlen(".fill"))==0 || - strncmp(Str, ".space", strlen(".space"))==0 || - strncmp(Str, ".zerofill", strlen(".zerofill"))==0 || - strncmp(Str, ".p2align", strlen(".p2align"))==0 || - strncmp(Str, ".p2alignw", strlen(".p2alignw"))==0 || - strncmp(Str, ".p2alignl", strlen(".p2alignl"))==0 || - strncmp(Str, ".align32", strlen(".p2align32"))==0 || - strncmp(Str, ".include", strlen(".include"))==0) - cerr << "Directive " << Str << " in asm may lead to invalid offsets for" << - " constant pools (the assembler will tell you if this happens).\n"; - // Some generate code, but this is only interesting in the text section. - else if (inTextSection) { - if (strncmp(Str, ".long", strlen(".long"))==0) - Length += 4*countArguments(Str+strlen(".long")); - else if (strncmp(Str, ".short", strlen(".short"))==0) - Length += 2*countArguments(Str+strlen(".short")); - else if (strncmp(Str, ".byte", strlen(".byte"))==0) - Length += 1*countArguments(Str+strlen(".byte")); - else if (strncmp(Str, ".single", strlen(".single"))==0) - Length += 4*countArguments(Str+strlen(".single")); - else if (strncmp(Str, ".double", strlen(".double"))==0) - Length += 8*countArguments(Str+strlen(".double")); - else if (strncmp(Str, ".quad", strlen(".quad"))==0) - Length += 16*countArguments(Str+strlen(".quad")); - else if (strncmp(Str, ".ascii", strlen(".ascii"))==0) - Length += countString(Str+strlen(".ascii")); - else if (strncmp(Str, ".asciz", strlen(".asciz"))==0) - Length += countString(Str+strlen(".asciz"))+1; - } - } else if (inTextSection) { - // An instruction - atInsnStart = false; - if (Subtarget->isThumb()) { - // BL and BLX <non-reg> are 4 bytes, all others 2. - if (strncmp(Str, "blx", strlen("blx"))==0) { - const char* p = Str+3; - while (*p && isspace(*p)) - p++; - if (*p == 'r' || *p=='R') - Length += 2; // BLX reg - else - Length += 4; // BLX non-reg - } else if (strncmp(Str, "bl", strlen("bl"))==0) - Length += 4; // BL - else - Length += 2; // Thumb anything else - } - else - Length += 4; // ARM - } - } - if (*Str == '\n' || *Str == BaseTAI::SeparatorChar) - atInsnStart = true; - } - free(s_copy); - return Length; -} - -// Instantiate default implementation. -TEMPLATE_INSTANTIATION(class ARMTargetAsmInfo<TargetAsmInfo>); diff --git a/lib/Target/ARM/ARMTargetAsmInfo.h b/lib/Target/ARM/ARMTargetAsmInfo.h deleted file mode 100644 index d3f2da0..0000000 --- a/lib/Target/ARM/ARMTargetAsmInfo.h +++ /dev/null @@ -1,63 +0,0 @@ -//=====-- ARMTargetAsmInfo.h - ARM asm properties -------------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the ARMTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef ARMTARGETASMINFO_H -#define ARMTARGETASMINFO_H - -#include "ARMTargetMachine.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" -#include "llvm/Target/DarwinTargetAsmInfo.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - - extern const char *const arm_asm_table[]; - - template <class BaseTAI> - struct ARMTargetAsmInfo : public BaseTAI { - explicit ARMTargetAsmInfo(const ARMBaseTargetMachine &TM) : BaseTAI(TM) { - BaseTAI::AsmTransCBE = arm_asm_table; - - BaseTAI::AlignmentIsInBytes = false; - BaseTAI::Data64bitsDirective = 0; - BaseTAI::CommentString = "@"; - BaseTAI::ConstantPoolSection = "\t.text\n"; - BaseTAI::COMMDirectiveTakesAlignment = false; - BaseTAI::InlineAsmStart = "@ InlineAsm Start"; - BaseTAI::InlineAsmEnd = "@ InlineAsm End"; - BaseTAI::LCOMMDirective = "\t.lcomm\t"; - } - - const ARMSubtarget *Subtarget; - - virtual unsigned getInlineAsmLength(const char *Str) const; - unsigned countArguments(const char *p) const; - unsigned countString(const char *p) const; - }; - - typedef ARMTargetAsmInfo<TargetAsmInfo> ARMGenericTargetAsmInfo; - - EXTERN_TEMPLATE_INSTANTIATION(class ARMTargetAsmInfo<TargetAsmInfo>); - - struct ARMDarwinTargetAsmInfo : public ARMTargetAsmInfo<DarwinTargetAsmInfo> { - explicit ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM); - }; - - struct ARMELFTargetAsmInfo : public ARMTargetAsmInfo<ELFTargetAsmInfo> { - explicit ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM); - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/Alpha/AlphaTargetAsmInfo.cpp b/lib/Target/Alpha/AlphaTargetAsmInfo.cpp deleted file mode 100644 index 6092ab6..0000000 --- a/lib/Target/Alpha/AlphaTargetAsmInfo.cpp +++ /dev/null @@ -1,31 +0,0 @@ -//===-- AlphaTargetAsmInfo.cpp - Alpha asm properties -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the AlphaTargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "AlphaTargetMachine.h" -#include "AlphaTargetAsmInfo.h" - -using namespace llvm; - -AlphaTargetAsmInfo::AlphaTargetAsmInfo(const AlphaTargetMachine &TM) - : TargetAsmInfo(TM) { - AlignmentIsInBytes = false; - PrivateGlobalPrefix = "$"; - JumpTableDirective = ".gprel32"; - JumpTableDataSection = "\t.section .rodata\n"; - WeakRefDirective = "\t.weak\t"; -} - -unsigned AlphaTargetAsmInfo::RelocBehaviour() const { - return (TM.getRelocationModel() != Reloc::Static ? - Reloc::LocalOrGlobal : Reloc::Global); -} diff --git a/lib/Target/Alpha/AlphaTargetAsmInfo.h b/lib/Target/Alpha/AlphaTargetAsmInfo.h deleted file mode 100644 index 7675b26..0000000 --- a/lib/Target/Alpha/AlphaTargetAsmInfo.h +++ /dev/null @@ -1,32 +0,0 @@ -//=====-- AlphaTargetAsmInfo.h - Alpha asm properties ---------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the AlphaTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef ALPHATARGETASMINFO_H -#define ALPHATARGETASMINFO_H - -#include "llvm/Target/TargetAsmInfo.h" - -namespace llvm { - - // Forward declaration. - class AlphaTargetMachine; - - struct AlphaTargetAsmInfo : public TargetAsmInfo { - explicit AlphaTargetAsmInfo(const AlphaTargetMachine &TM); - - virtual unsigned RelocBehaviour() const; - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp deleted file mode 100644 index 2868ff7..0000000 --- a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp +++ /dev/null @@ -1,73 +0,0 @@ -//===-- SPUTargetAsmInfo.cpp - Cell SPU asm properties ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the SPUTargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "SPUTargetAsmInfo.h" -#include "SPUTargetMachine.h" -#include "llvm/Function.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Dwarf.h" - -using namespace llvm; -using namespace llvm::dwarf; - -SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) : - SPUTargetAsmInfo<ELFTargetAsmInfo>(TM) { - PCSymbol = "."; - CommentString = "#"; - GlobalPrefix = ""; - PrivateGlobalPrefix = ".L"; - // This corresponds to what the gcc SPU compiler emits, for consistency. - CStringSection = ".rodata.str"; - - // Has leb128, .loc and .file - HasLEB128 = true; - HasDotLocAndDotFile = true; - - // BSS section needs to be emitted as ".section" - BSSSection = "\t.section\t.bss"; - BSSSection_ = getUnnamedSection("\t.section\t.bss", - SectionFlags::Writeable | SectionFlags::BSS, - true); - - SupportsDebugInformation = true; - NeedsSet = true; - DwarfAbbrevSection = "\t.section .debug_abbrev,\"\",@progbits"; - DwarfInfoSection = "\t.section .debug_info,\"\",@progbits"; - DwarfLineSection = "\t.section .debug_line,\"\",@progbits"; - DwarfFrameSection = "\t.section .debug_frame,\"\",@progbits"; - DwarfPubNamesSection = "\t.section .debug_pubnames,\"\",@progbits"; - DwarfPubTypesSection = "\t.section .debug_pubtypes,\"\",progbits"; - DwarfStrSection = "\t.section .debug_str,\"MS\",@progbits,1"; - DwarfLocSection = "\t.section .debug_loc,\"\",@progbits"; - DwarfARangesSection = "\t.section .debug_aranges,\"\",@progbits"; - DwarfRangesSection = "\t.section .debug_ranges,\"\",@progbits"; - DwarfMacroInfoSection = 0; // macro info not supported. - - // Exception handling is not supported on CellSPU (think about it: you only - // have 256K for code+data. Would you support exception handling?) - SupportsExceptionHandling = false; -} - -/// PreferredEHDataFormat - This hook allows the target to select data -/// format used for encoding pointers in exception handling data. Reason is -/// 0 for data, 1 for code labels, 2 for function pointers. Global is true -/// if the symbol can be relocated. -unsigned -SPULinuxTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - // We really need to write something here. - return TargetAsmInfo::PreferredEHDataFormat(Reason, Global); -} - -// Instantiate default implementation. -TEMPLATE_INSTANTIATION(class SPUTargetAsmInfo<TargetAsmInfo>); diff --git a/lib/Target/CellSPU/SPUTargetAsmInfo.h b/lib/Target/CellSPU/SPUTargetAsmInfo.h deleted file mode 100644 index d10a565..0000000 --- a/lib/Target/CellSPU/SPUTargetAsmInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -//===-- SPUTargetAsmInfo.h - Cell SPU asm properties -----------*- C++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the SPUTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef SPUTARGETASMINFO_H -#define SPUTARGETASMINFO_H - -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" -#include "SPUTargetMachine.h" -#include "SPUSubtarget.h" - -namespace llvm { - - // Forward declaration. - class SPUTargetMachine; - - template <class BaseTAI> - struct SPUTargetAsmInfo : public BaseTAI { - explicit SPUTargetAsmInfo(const SPUTargetMachine &TM): - BaseTAI(TM) { - /* (unused today) - * const SPUSubtarget *Subtarget = &TM.getSubtarget<SPUSubtarget>(); */ - - BaseTAI::ZeroDirective = "\t.space\t"; - BaseTAI::SetDirective = "\t.set"; - BaseTAI::Data64bitsDirective = "\t.quad\t"; - BaseTAI::AlignmentIsInBytes = false; - BaseTAI::LCOMMDirective = "\t.lcomm\t"; - BaseTAI::InlineAsmStart = "# InlineAsm Start"; - BaseTAI::InlineAsmEnd = "# InlineAsm End"; - } - }; - - struct SPULinuxTargetAsmInfo : public SPUTargetAsmInfo<ELFTargetAsmInfo> { - explicit SPULinuxTargetAsmInfo(const SPUTargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - }; -} // namespace llvm - -#endif /* SPUTARGETASMINFO_H */ diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp deleted file mode 100644 index d7d675a..0000000 --- a/lib/Target/DarwinTargetAsmInfo.cpp +++ /dev/null @@ -1,216 +0,0 @@ -//===-- DarwinTargetAsmInfo.cpp - Darwin asm properties ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines target asm properties related what form asm statements -// should take in general on Darwin-based targets -// -//===----------------------------------------------------------------------===// - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Target/DarwinTargetAsmInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetData.h" - -using namespace llvm; - -DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) - : TargetAsmInfo(TM) { - - CStringSection_ = getUnnamedSection("\t.cstring", - SectionFlags::Mergeable | SectionFlags::Strings); - FourByteConstantSection = getUnnamedSection("\t.literal4\n", - SectionFlags::Mergeable); - EightByteConstantSection = getUnnamedSection("\t.literal8\n", - SectionFlags::Mergeable); - - // Note: 16-byte constant section is subtarget specific and should be provided - // there, if needed. - SixteenByteConstantSection = 0; - - ReadOnlySection = getUnnamedSection("\t.const\n", SectionFlags::None); - - TextCoalSection = - getNamedSection("\t__TEXT,__textcoal_nt,coalesced,pure_instructions", - SectionFlags::Code); - ConstTextCoalSection = getNamedSection("\t__TEXT,__const_coal,coalesced", - SectionFlags::None); - ConstDataCoalSection = getNamedSection("\t__DATA,__const_coal,coalesced", - SectionFlags::None); - ConstDataSection = getUnnamedSection(".const_data", SectionFlags::None); - DataCoalSection = getNamedSection("\t__DATA,__datacoal_nt,coalesced", - SectionFlags::Writeable); - - - // Common settings for all Darwin targets. - // Syntax: - GlobalPrefix = "_"; - PrivateGlobalPrefix = "L"; - LessPrivateGlobalPrefix = "l"; // Marker for some ObjC metadata - StringConstantPrefix = "\1LC"; - NeedsSet = true; - NeedsIndirectEncoding = true; - AllowQuotesInName = true; - HasSingleParameterDotFile = false; - - // In non-PIC modes, emit a special label before jump tables so that the - // linker can perform more accurate dead code stripping. We do not check the - // relocation model here since it can be overridden later. - JumpTableSpecialLabelPrefix = "l"; - - // Directives: - WeakDefDirective = "\t.weak_definition "; - WeakRefDirective = "\t.weak_reference "; - HiddenDirective = "\t.private_extern "; - - // Sections: - CStringSection = "\t.cstring"; - JumpTableDataSection = "\t.const\n"; - BSSSection = 0; - - if (TM.getRelocationModel() == Reloc::Static) { - StaticCtorsSection = ".constructor"; - StaticDtorsSection = ".destructor"; - } else { - StaticCtorsSection = ".mod_init_func"; - StaticDtorsSection = ".mod_term_func"; - } - - DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; - DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; - DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; - DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; - DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; - DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; - DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; - DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; - DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; - DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; - DwarfMacroInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; -} - -/// emitUsedDirectiveFor - On Darwin, internally linked data beginning with -/// the PrivateGlobalPrefix or the LessPrivateGlobalPrefix does not have the -/// directive emitted (this occurs in ObjC metadata). - -bool -DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV, - Mangler *Mang) const { - if (GV==0) - return false; - if (GV->hasLocalLinkage() && !isa<Function>(GV) && - ((strlen(getPrivateGlobalPrefix()) != 0 && - Mang->getValueName(GV).substr(0,strlen(getPrivateGlobalPrefix())) == - getPrivateGlobalPrefix()) || - (strlen(getLessPrivateGlobalPrefix()) != 0 && - Mang->getValueName(GV).substr(0,strlen(getLessPrivateGlobalPrefix())) == - getLessPrivateGlobalPrefix()))) - return false; - return true; -} - -const Section* -DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { - SectionKind::Kind Kind = SectionKindForGlobal(GV); - bool isWeak = GV->isWeakForLinker(); - bool isNonStatic = TM.getRelocationModel() != Reloc::Static; - - switch (Kind) { - case SectionKind::Text: - if (isWeak) - return TextCoalSection; - else - return TextSection; - case SectionKind::Data: - case SectionKind::ThreadData: - case SectionKind::BSS: - case SectionKind::ThreadBSS: - if (cast<GlobalVariable>(GV)->isConstant()) - return (isWeak ? ConstDataCoalSection : ConstDataSection); - else - return (isWeak ? DataCoalSection : DataSection); - case SectionKind::ROData: - return (isWeak ? ConstDataCoalSection : - (isNonStatic ? ConstDataSection : getReadOnlySection())); - case SectionKind::RODataMergeStr: - return (isWeak ? - ConstTextCoalSection : - MergeableStringSection(cast<GlobalVariable>(GV))); - case SectionKind::RODataMergeConst: - return (isWeak ? - ConstDataCoalSection: - MergeableConstSection(cast<GlobalVariable>(GV))); - default: - assert(0 && "Unsuported section kind for global"); - } - - // FIXME: Do we have any extra special weird cases? - return NULL; -} - -const Section* -DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { - const TargetData *TD = TM.getTargetData(); - Constant *C = cast<GlobalVariable>(GV)->getInitializer(); - const Type *Ty = cast<ArrayType>(C->getType())->getElementType(); - - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size) { - unsigned Align = TD->getPreferredAlignment(GV); - if (Align <= 32) - return getCStringSection_(); - } - - return getReadOnlySection(); -} - -const Section* -DarwinTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { - Constant *C = GV->getInitializer(); - - return MergeableConstSection(C->getType()); -} - -inline const Section* -DarwinTargetAsmInfo::MergeableConstSection(const Type *Ty) const { - const TargetData *TD = TM.getTargetData(); - - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size == 4) - return FourByteConstantSection; - else if (Size == 8) - return EightByteConstantSection; - else if (Size == 16 && SixteenByteConstantSection) - return SixteenByteConstantSection; - - return getReadOnlySection(); -} - -const Section* -DarwinTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { - const Section* S = MergeableConstSection(Ty); - - // Handle weird special case, when compiling PIC stuff. - if (S == getReadOnlySection() && - TM.getRelocationModel() != Reloc::Static) - return ConstDataSection; - - return S; -} - -std::string -DarwinTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, - SectionKind::Kind kind) const { - assert(0 && "Darwin does not use unique sections"); - return ""; -} diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp deleted file mode 100644 index 8f6e96e..0000000 --- a/lib/Target/ELFTargetAsmInfo.cpp +++ /dev/null @@ -1,227 +0,0 @@ -//===-- ELFTargetAsmInfo.cpp - ELF asm properties ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines target asm properties related what form asm statements -// should take in general on ELF-based targets -// -//===----------------------------------------------------------------------===// - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/Target/ELFTargetAsmInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetData.h" - -using namespace llvm; - -ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) - : TargetAsmInfo(TM) { - - BSSSection_ = getUnnamedSection("\t.bss", - SectionFlags::Writeable | SectionFlags::BSS); - ReadOnlySection = getNamedSection("\t.rodata", SectionFlags::None); - TLSDataSection = getNamedSection("\t.tdata", - SectionFlags::Writeable | SectionFlags::TLS); - TLSBSSSection = getNamedSection("\t.tbss", - SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS); - - DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writeable); - DataRelLocalSection = getNamedSection("\t.data.rel.local", - SectionFlags::Writeable); - DataRelROSection = getNamedSection("\t.data.rel.ro", - SectionFlags::Writeable); - DataRelROLocalSection = getNamedSection("\t.data.rel.ro.local", - SectionFlags::Writeable); -} - -SectionKind::Kind -ELFTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { - SectionKind::Kind Kind = TargetAsmInfo::SectionKindForGlobal(GV); - - if (Kind != SectionKind::Data) - return Kind; - - // Decide, whether we need data.rel stuff - const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV); - if (GVar->hasInitializer()) { - Constant *C = GVar->getInitializer(); - bool isConstant = GVar->isConstant(); - unsigned Reloc = RelocBehaviour(); - if (Reloc != Reloc::None && C->ContainsRelocations(Reloc)) - return (C->ContainsRelocations(Reloc::Global) ? - (isConstant ? - SectionKind::DataRelRO : SectionKind::DataRel) : - (isConstant ? - SectionKind::DataRelROLocal : SectionKind::DataRelLocal)); - } - - return Kind; -} - -const Section* -ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { - SectionKind::Kind Kind = SectionKindForGlobal(GV); - - if (const Function *F = dyn_cast<Function>(GV)) { - switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); - case Function::PrivateLinkage: - case Function::InternalLinkage: - case Function::DLLExportLinkage: - case Function::ExternalLinkage: - return TextSection; - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - std::string Name = UniqueSectionForGlobal(GV, Kind); - unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); - return getNamedSection(Name.c_str(), Flags); - } - } else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { - if (GVar->isWeakForLinker()) { - std::string Name = UniqueSectionForGlobal(GVar, Kind); - unsigned Flags = SectionFlagsForGlobal(GVar, Name.c_str()); - return getNamedSection(Name.c_str(), Flags); - } else { - switch (Kind) { - case SectionKind::Data: - case SectionKind::SmallData: - return DataSection; - case SectionKind::DataRel: - return DataRelSection; - case SectionKind::DataRelLocal: - return DataRelLocalSection; - case SectionKind::DataRelRO: - return DataRelROSection; - case SectionKind::DataRelROLocal: - return DataRelROLocalSection; - case SectionKind::BSS: - case SectionKind::SmallBSS: - // ELF targets usually have BSS sections - return getBSSSection_(); - case SectionKind::ROData: - case SectionKind::SmallROData: - return getReadOnlySection(); - case SectionKind::RODataMergeStr: - return MergeableStringSection(GVar); - case SectionKind::RODataMergeConst: - return MergeableConstSection(GVar); - case SectionKind::ThreadData: - // ELF targets usually support TLS stuff - return TLSDataSection; - case SectionKind::ThreadBSS: - return TLSBSSSection; - default: - assert(0 && "Unsuported section kind for global"); - } - } - } else - assert(0 && "Unsupported global"); - - return NULL; -} - -const Section* -ELFTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { - // FIXME: Support data.rel stuff someday - return MergeableConstSection(Ty); -} - -const Section* -ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { - Constant *C = GV->getInitializer(); - return MergeableConstSection(C->getType()); -} - -inline const Section* -ELFTargetAsmInfo::MergeableConstSection(const Type *Ty) const { - const TargetData *TD = TM.getTargetData(); - - // FIXME: string here is temporary, until stuff will fully land in. - // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's - // currently directly used by asmprinter. - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size == 4 || Size == 8 || Size == 16) { - std::string Name = ".rodata.cst" + utostr(Size); - - return getNamedSection(Name.c_str(), - SectionFlags::setEntitySize(SectionFlags::Mergeable, - Size)); - } - - return getReadOnlySection(); -} - -const Section* -ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { - const TargetData *TD = TM.getTargetData(); - Constant *C = cast<GlobalVariable>(GV)->getInitializer(); - const Type *Ty = cast<ArrayType>(C->getType())->getElementType(); - - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size <= 16) { - assert(getCStringSection() && "Should have string section prefix"); - - // We also need alignment here - unsigned Align = TD->getPrefTypeAlignment(Ty); - if (Align < Size) - Align = Size; - - std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align); - unsigned Flags = SectionFlags::setEntitySize(SectionFlags::Mergeable | - SectionFlags::Strings, - Size); - return getNamedSection(Name.c_str(), Flags); - } - - return getReadOnlySection(); -} - -std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const { - std::string Flags = ",\""; - - if (!(flags & SectionFlags::Debug)) - Flags += 'a'; - if (flags & SectionFlags::Code) - Flags += 'x'; - if (flags & SectionFlags::Writeable) - Flags += 'w'; - if (flags & SectionFlags::Mergeable) - Flags += 'M'; - if (flags & SectionFlags::Strings) - Flags += 'S'; - if (flags & SectionFlags::TLS) - Flags += 'T'; - if (flags & SectionFlags::Small) - Flags += 's'; - - Flags += "\","; - - // If comment string is '@', e.g. as on ARM - use '%' instead - if (strcmp(CommentString, "@") == 0) - Flags += '%'; - else - Flags += '@'; - - // FIXME: There can be exceptions here - if (flags & SectionFlags::BSS) - Flags += "nobits"; - else - Flags += "progbits"; - - if (unsigned entitySize = SectionFlags::getEntitySize(flags)) - Flags += "," + utostr(entitySize); - - return Flags; -} diff --git a/lib/Target/IA64/AsmPrinter/CMakeLists.txt b/lib/Target/IA64/AsmPrinter/CMakeLists.txt deleted file mode 100644 index ffe0eed..0000000 --- a/lib/Target/IA64/AsmPrinter/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include_directories(
- ${CMAKE_CURRENT_BINARY_DIR}/..
- ${CMAKE_CURRENT_SOURCE_DIR}/..
- )
-
-add_llvm_library(LLVMIA64AsmPrinter
- IA64AsmPrinter.cpp
- )
-add_dependencies(LLVMIA64AsmPrinter IA64CodeGenTable_gen)
\ No newline at end of file diff --git a/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp b/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp deleted file mode 100644 index d85c0ea..0000000 --- a/lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp +++ /dev/null @@ -1,389 +0,0 @@ -//===-- IA64AsmPrinter.cpp - Print out IA64 LLVM as assembly --------------===// -// -// 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 assembly accepted by the GNU binutils 'gas' -// assembler. The Intel 'ias' and HP-UX 'as' assemblers *may* choke on this -// output, but if so that's a bug I'd like to hear about: please file a bug -// report in bugzilla. FYI, the not too bad 'ias' assembler is bundled with -// the Intel C/C++ compiler for Itanium Linux. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "IA64.h" -#include "IA64TargetMachine.h" -#include "llvm/Module.h" -#include "llvm/MDNode.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/Statistic.h" -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -namespace { - class IA64AsmPrinter : public AsmPrinter { - std::set<std::string> ExternalFunctionNames, ExternalObjectNames; - public: - explicit IA64AsmPrinter(raw_ostream &O, TargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V) {} - - virtual const char *getPassName() const { - return "IA64 Assembly Printer"; - } - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - // This method is used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo){ - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.getType() == MachineOperand::MO_Register) { - assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Not physref??"); - //XXX Bug Workaround: See note in Printer::doInitialization about %. - O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; - } else { - printOp(MO); - } - } - - void printS8ImmOperand(const MachineInstr *MI, unsigned OpNo) { - int val=(unsigned int)MI->getOperand(OpNo).getImm(); - if(val>=128) val=val-256; // if negative, flip sign - O << val; - } - void printS14ImmOperand(const MachineInstr *MI, unsigned OpNo) { - int val=(unsigned int)MI->getOperand(OpNo).getImm(); - if(val>=8192) val=val-16384; // if negative, flip sign - O << val; - } - void printS22ImmOperand(const MachineInstr *MI, unsigned OpNo) { - int val=(unsigned int)MI->getOperand(OpNo).getImm(); - if(val>=2097152) val=val-4194304; // if negative, flip sign - O << val; - } - void printU64ImmOperand(const MachineInstr *MI, unsigned OpNo) { - O << (uint64_t)MI->getOperand(OpNo).getImm(); - } - void printS64ImmOperand(const MachineInstr *MI, unsigned OpNo) { -// XXX : nasty hack to avoid GPREL22 "relocation truncated to fit" linker -// errors - instead of add rX = @gprel(CPI<whatever>), r1;; we now -// emit movl rX = @gprel(CPI<whatever);; -// add rX = rX, r1; -// this gives us 64 bits instead of 22 (for the add long imm) to play -// with, which shuts up the linker. The problem is that the constant -// pool entries aren't immediates at this stage, so we check here. -// If it's an immediate, print it the old fashioned way. If it's -// not, we print it as a constant pool index. - if (MI->getOperand(OpNo).isImm()) { - O << (int64_t)MI->getOperand(OpNo).getImm(); - } else { // this is a constant pool reference: FIXME: assert this - printOp(MI->getOperand(OpNo)); - } - } - - void printGlobalOperand(const MachineInstr *MI, unsigned OpNo) { - printOp(MI->getOperand(OpNo), false); // this is NOT a br.call instruction - } - - void printCallOperand(const MachineInstr *MI, unsigned OpNo) { - printOp(MI->getOperand(OpNo), true); // this is a br.call instruction - } - - void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, bool isBRCALLinsn= false); - void printModuleLevelGV(const GlobalVariable* GVar); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - }; -} // end of anonymous namespace - - -// Include the auto-generated portion of the assembly writer. -#include "IA64GenAsmWriter.inc" - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool IA64AsmPrinter::runOnMachineFunction(MachineFunction &MF) { - this->MF = &MF; - - SetupMachineFunction(MF); - O << "\n\n"; - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - const Function *F = MF.getFunction(); - SwitchToSection(TAI->SectionForGlobal(F)); - - // Print out labels for the function. - EmitAlignment(MF.getAlignment()); - O << "\t.global\t" << CurrentFnName << '\n'; - - printVisibility(CurrentFnName, F->getVisibility()); - - O << "\t.type\t" << CurrentFnName << ", @function\n"; - O << CurrentFnName << ":\n"; - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block if there are any predecessors. - if (!I->pred_empty()) { - printBasicBlockLabel(I, true, true); - O << '\n'; - } - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - printMachineInstruction(II); - } - } - - // We didn't modify anything. - return false; -} - -void IA64AsmPrinter::printOp(const MachineOperand &MO, - bool isBRCALLinsn /* = false */) { - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); - switch (MO.getType()) { - case MachineOperand::MO_Register: - O << RI.get(MO.getReg()).AsmName; - return; - - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; - case MachineOperand::MO_ConstantPoolIndex: { - O << "@gprel(" << TAI->getPrivateGlobalPrefix() - << "CPI" << getFunctionNumber() << "_" << MO.getIndex() << ")"; - return; - } - - case MachineOperand::MO_GlobalAddress: { - - // functions need @ltoff(@fptr(fn_name)) form - GlobalValue *GV = MO.getGlobal(); - Function *F = dyn_cast<Function>(GV); - - bool Needfptr=false; // if we're computing an address @ltoff(X), do - // we need to decorate it so it becomes - // @ltoff(@fptr(X)) ? - if (F && !isBRCALLinsn /*&& F->isDeclaration()*/) - Needfptr=true; - - // if this is the target of a call instruction, we should define - // the function somewhere (GNU gas has no problem without this, but - // Intel ias rightly complains of an 'undefined symbol') - - if (F /*&& isBRCALLinsn*/ && F->isDeclaration()) - ExternalFunctionNames.insert(Mang->getValueName(MO.getGlobal())); - else - if (GV->isDeclaration()) // e.g. stuff like 'stdin' - ExternalObjectNames.insert(Mang->getValueName(MO.getGlobal())); - - if (!isBRCALLinsn) - O << "@ltoff("; - if (Needfptr) - O << "@fptr("; - O << Mang->getValueName(MO.getGlobal()); - - if (Needfptr && !isBRCALLinsn) - O << "#))"; // close both fptr( and ltoff( - else { - if (Needfptr) - O << "#)"; // close only fptr( - if (!isBRCALLinsn) - O << "#)"; // close only ltoff( - } - - int Offset = MO.getOffset(); - if (Offset > 0) - O << " + " << Offset; - else if (Offset < 0) - O << " - " << -Offset; - return; - } - case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); - ExternalFunctionNames.insert(MO.getSymbolName()); - return; - default: - O << "<AsmPrinter: unknown operand type: " << MO.getType() << " >"; return; - } -} - -/// printMachineInstruction -- Print out a single IA64 LLVM instruction -/// MI to the current output stream. -/// -void IA64AsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -bool IA64AsmPrinter::doInitialization(Module &M) { - bool Result = AsmPrinter::doInitialization(M); - - O << "\n.ident \"LLVM-ia64\"\n\n" - << "\t.psr lsb\n" // should be "msb" on HP-UX, for starters - << "\t.radix C\n" - << "\t.psr abi64\n"; // we only support 64 bits for now - return Result; -} - -void IA64AsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { - const TargetData *TD = TM.getTargetData(); - - if (!GVar->hasInitializer()) - return; // External global require no code - - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(GVar)) - return; - - O << "\n\n"; - std::string name = Mang->getValueName(GVar); - Constant *C = GVar->getInitializer(); - if (isa<MDNode>(C) || isa<MDString>(C)) - return; - unsigned Size = TD->getTypeAllocSize(C->getType()); - unsigned Align = TD->getPreferredAlignmentLog(GVar); - - printVisibility(name, GVar->getVisibility()); - - SwitchToSection(TAI->SectionForGlobal(GVar)); - - if (C->isNullValue() && !GVar->hasSection()) { - if (!GVar->isThreadLocal() && - (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (GVar->hasLocalLinkage()) { - O << "\t.lcomm " << name << "#," << Size - << ',' << (1 << Align); - O << '\n'; - } else { - O << "\t.common " << name << "#," << Size - << ',' << (1 << Align); - O << '\n'; - } - - return; - } - } - - switch (GVar->getLinkage()) { - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::CommonLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - // Nonnull linkonce -> weak - O << "\t.weak " << name << '\n'; - break; - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << TAI->getGlobalDirective() << name << '\n'; - // FALL THROUGH - case GlobalValue::InternalLinkage: - case GlobalValue::PrivateLinkage: - break; - case GlobalValue::GhostLinkage: - cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n"; - abort(); - case GlobalValue::DLLImportLinkage: - cerr << "DLLImport linkage is not supported by this target!\n"; - abort(); - case GlobalValue::DLLExportLinkage: - cerr << "DLLExport linkage is not supported by this target!\n"; - abort(); - default: - assert(0 && "Unknown linkage type!"); - } - - EmitAlignment(Align, GVar); - - if (TAI->hasDotTypeDotSizeDirective()) { - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << ',' << Size << '\n'; - } - - O << name << ":\n"; - EmitGlobalConstant(C); -} - - -bool IA64AsmPrinter::doFinalization(Module &M) { - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - printModuleLevelGV(I); - - // we print out ".global X \n .type X, @function" for each external function - O << "\n\n// br.call targets referenced (and not defined) above: \n"; - for (std::set<std::string>::iterator i = ExternalFunctionNames.begin(), - e = ExternalFunctionNames.end(); i!=e; ++i) { - O << "\t.global " << *i << "\n\t.type " << *i << ", @function\n"; - } - O << "\n\n"; - - // we print out ".global X \n .type X, @object" for each external object - O << "\n\n// (external) symbols referenced (and not defined) above: \n"; - for (std::set<std::string>::iterator i = ExternalObjectNames.begin(), - e = ExternalObjectNames.end(); i!=e; ++i) { - O << "\t.global " << *i << "\n\t.type " << *i << ", @object\n"; - } - O << "\n\n"; - - return AsmPrinter::doFinalization(M); -} - -/// createIA64CodePrinterPass - Returns a pass that prints the IA64 -/// assembly code for a MachineFunction to the given output stream, using -/// the given target machine description. -/// -FunctionPass *llvm::createIA64CodePrinterPass(raw_ostream &o, - IA64TargetMachine &tm, - bool verbose) { - return new IA64AsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); -} - -namespace { - static struct Register { - Register() { - IA64TargetMachine::registerAsmPrinter(createIA64CodePrinterPass); - } - } Registrator; -} - - -// Force static initialization. -extern "C" void LLVMInitializeIA64AsmPrinter() { } diff --git a/lib/Target/IA64/AsmPrinter/Makefile b/lib/Target/IA64/AsmPrinter/Makefile deleted file mode 100644 index 12880f3..0000000 --- a/lib/Target/IA64/AsmPrinter/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- lib/Target/IA64/AsmPrinter/Makefile -----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../../.. -LIBRARYNAME = LLVMIA64AsmPrinter - -# Hack: we need to include 'main' IA64 target directory to grab -# private headers -CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common diff --git a/lib/Target/IA64/CMakeLists.txt b/lib/Target/IA64/CMakeLists.txt deleted file mode 100644 index 638ed2e..0000000 --- a/lib/Target/IA64/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS IA64.td) - -tablegen(IA64GenRegisterInfo.h.inc -gen-register-desc-header) -tablegen(IA64GenRegisterNames.inc -gen-register-enums) -tablegen(IA64GenRegisterInfo.inc -gen-register-desc) -tablegen(IA64GenInstrNames.inc -gen-instr-enums) -tablegen(IA64GenInstrInfo.inc -gen-instr-desc) -tablegen(IA64GenAsmWriter.inc -gen-asm-writer) -tablegen(IA64GenDAGISel.inc -gen-dag-isel) - -add_llvm_target(IA64CodeGen - IA64Bundling.cpp - IA64InstrInfo.cpp - IA64ISelDAGToDAG.cpp - IA64ISelLowering.cpp - IA64RegisterInfo.cpp - IA64Subtarget.cpp - IA64TargetAsmInfo.cpp - IA64TargetMachine.cpp - ) - -target_link_libraries (LLVMIA64CodeGen LLVMSelectionDAG) diff --git a/lib/Target/IA64/IA64.h b/lib/Target/IA64/IA64.h deleted file mode 100644 index 9c758fd..0000000 --- a/lib/Target/IA64/IA64.h +++ /dev/null @@ -1,57 +0,0 @@ -//===-- IA64.h - Top-level interface for IA64 representation ------*- C++ -*-===// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the entry points for global functions defined in the IA64 -// target library, as used by the LLVM JIT. -// -//===----------------------------------------------------------------------===// - -#ifndef TARGET_IA64_H -#define TARGET_IA64_H - -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - -class IA64TargetMachine; -class FunctionPass; -class raw_ostream; - -/// createIA64DAGToDAGInstructionSelector - This pass converts an LLVM -/// function into IA64 machine code in a sane, DAG->DAG transform. -/// -FunctionPass *createIA64DAGToDAGInstructionSelector(IA64TargetMachine &TM); - -/// createIA64BundlingPass - This pass adds stop bits and bundles -/// instructions. -/// -FunctionPass *createIA64BundlingPass(IA64TargetMachine &TM); - -/// createIA64CodePrinterPass - Returns a pass that prints the IA64 -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *createIA64CodePrinterPass(raw_ostream &o, - IA64TargetMachine &tm, - bool verbose); - -} // End llvm namespace - -// Defines symbolic names for IA64 registers. This defines a mapping from -// register name to register number. -// -#include "IA64GenRegisterNames.inc" - -// Defines symbolic names for the IA64 instructions. -// -#include "IA64GenInstrNames.inc" - -#endif - - diff --git a/lib/Target/IA64/IA64.td b/lib/Target/IA64/IA64.td deleted file mode 100644 index c469281..0000000 --- a/lib/Target/IA64/IA64.td +++ /dev/null @@ -1,39 +0,0 @@ -//===-- IA64.td - Target definition file for Intel IA64 -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This is a target description file for the Intel IA64 architecture, -// also known variously as ia64, IA-64, IPF, "the Itanium architecture" etc. -// -//===----------------------------------------------------------------------===// - -// Get the target-independent interfaces which we are implementing... -// -include "llvm/Target/Target.td" - -//===----------------------------------------------------------------------===// -// Register File Description -//===----------------------------------------------------------------------===// - -include "IA64RegisterInfo.td" - -//===----------------------------------------------------------------------===// -// Instruction Descriptions -//===----------------------------------------------------------------------===// - -include "IA64InstrInfo.td" - -def IA64InstrInfo : InstrInfo { } - -def IA64 : Target { - // Our instruction set - let InstructionSet = IA64InstrInfo; - -} - - diff --git a/lib/Target/IA64/IA64Bundling.cpp b/lib/Target/IA64/IA64Bundling.cpp deleted file mode 100644 index 3a9ba6c..0000000 --- a/lib/Target/IA64/IA64Bundling.cpp +++ /dev/null @@ -1,118 +0,0 @@ -//===-- IA64Bundling.cpp - IA-64 instruction bundling pass. ------------ --===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Add stops where required to prevent read-after-write and write-after-write -// dependencies, for both registers and memory addresses. There are exceptions: -// -// - Compare instructions (cmp*, tbit, tnat, fcmp, frcpa) are OK with -// WAW dependencies so long as they all target p0, or are of parallel -// type (.and*/.or*) -// -// FIXME: bundling, for now, is left to the assembler. -// FIXME: this might be an appropriate place to translate between different -// instructions that do the same thing, if this helps bundling. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "ia64-codegen" -#include "IA64.h" -#include "IA64InstrInfo.h" -#include "IA64TargetMachine.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/ADT/SetOperations.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/Debug.h" -#include <set> -using namespace llvm; - -STATISTIC(StopBitsAdded, "Number of stop bits added"); - -namespace { - struct IA64BundlingPass : public MachineFunctionPass { - static char ID; - /// Target machine description which we query for reg. names, data - /// layout, etc. - /// - IA64TargetMachine &TM; - - IA64BundlingPass(IA64TargetMachine &tm) - : MachineFunctionPass(&ID), TM(tm) { } - - virtual const char *getPassName() const { - return "IA64 (Itanium) Bundling Pass"; - } - - bool runOnMachineBasicBlock(MachineBasicBlock &MBB); - bool runOnMachineFunction(MachineFunction &F) { - bool Changed = false; - for (MachineFunction::iterator FI = F.begin(), FE = F.end(); - FI != FE; ++FI) - Changed |= runOnMachineBasicBlock(*FI); - return Changed; - } - - // XXX: ugly global, but pending writes can cross basic blocks. Note that - // taken branches end instruction groups. So we only need to worry about - // 'fallthrough' code - std::set<unsigned> PendingRegWrites; - }; - char IA64BundlingPass::ID = 0; -} // end of anonymous namespace - -/// createIA64BundlingPass - Returns a pass that adds STOP (;;) instructions -/// and arranges the result into bundles. -/// -FunctionPass *llvm::createIA64BundlingPass(IA64TargetMachine &tm) { - return new IA64BundlingPass(tm); -} - -/// runOnMachineBasicBlock - add stops and bundle this MBB. -/// -bool IA64BundlingPass::runOnMachineBasicBlock(MachineBasicBlock &MBB) { - bool Changed = false; - - for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) { - MachineInstr *CurrentInsn = I++; - std::set<unsigned> CurrentReads, CurrentWrites, OrigWrites; - - for(unsigned i=0; i < CurrentInsn->getNumOperands(); i++) { - MachineOperand &MO=CurrentInsn->getOperand(i); - if (MO.isReg()) { - if(MO.isUse()) { // TODO: exclude p0 - CurrentReads.insert(MO.getReg()); - } - if(MO.isDef()) { // TODO: exclude p0 - CurrentWrites.insert(MO.getReg()); - OrigWrites.insert(MO.getReg()); // FIXME: use a nondestructive - // set_intersect instead? - } - } - } - - // CurrentReads/CurrentWrites contain info for the current instruction. - // Does it read or write any registers that are pending a write? - // (i.e. not separated by a stop) - set_intersect(CurrentReads, PendingRegWrites); - set_intersect(CurrentWrites, PendingRegWrites); - - if(! (CurrentReads.empty() && CurrentWrites.empty()) ) { - // there is a conflict, insert a stop and reset PendingRegWrites - CurrentInsn = BuildMI(MBB, CurrentInsn, CurrentInsn->getDebugLoc(), - TM.getInstrInfo()->get(IA64::STOP), 0); - PendingRegWrites=OrigWrites; // carry over current writes to next insn - Changed=true; StopBitsAdded++; // update stats - } else { // otherwise, track additional pending writes - set_union(PendingRegWrites, OrigWrites); - } - } // onto the next insn in the MBB - - return Changed; -} - diff --git a/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/lib/Target/IA64/IA64ISelDAGToDAG.cpp deleted file mode 100644 index 9800c50..0000000 --- a/lib/Target/IA64/IA64ISelDAGToDAG.cpp +++ /dev/null @@ -1,575 +0,0 @@ -//===---- IA64ISelDAGToDAG.cpp - IA64 pattern matching inst selector ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a pattern matching instruction selector for IA64, -// converting a legalized dag to an IA64 dag. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "ia64-codegen" -#include "IA64.h" -#include "IA64TargetMachine.h" -#include "IA64ISelLowering.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Constants.h" -#include "llvm/GlobalValue.h" -#include "llvm/Intrinsics.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" -using namespace llvm; - -namespace { - //===--------------------------------------------------------------------===// - /// IA64DAGToDAGISel - IA64 specific code to select IA64 machine - /// instructions for SelectionDAG operations. - /// - class IA64DAGToDAGISel : public SelectionDAGISel { - unsigned GlobalBaseReg; - public: - explicit IA64DAGToDAGISel(IA64TargetMachine &TM) - : SelectionDAGISel(TM) {} - - virtual bool runOnFunction(Function &Fn) { - // Make sure we re-emit a set of the global base reg if necessary - GlobalBaseReg = 0; - return SelectionDAGISel::runOnFunction(Fn); - } - - /// getI64Imm - Return a target constant with the specified value, of type - /// i64. - inline SDValue getI64Imm(uint64_t Imm) { - return CurDAG->getTargetConstant(Imm, MVT::i64); - } - - /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC - /// base register. Return the virtual register that holds this value. - // SDValue getGlobalBaseReg(); TODO: hmm - - // Select - Convert the specified operand from a target-independent to a - // target-specific node if it hasn't already been changed. - SDNode *Select(SDValue N); - - SDNode *SelectIntImmediateExpr(SDValue LHS, SDValue RHS, - unsigned OCHi, unsigned OCLo, - bool IsArithmetic = false, - bool Negate = false); - SDNode *SelectBitfieldInsert(SDNode *N); - - /// SelectCC - Select a comparison of the specified values with the - /// specified condition code, returning the CR# of the expression. - SDValue SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC); - - /// SelectAddr - Given the specified address, return the two operands for a - /// load/store instruction, and return true if it should be an indexed [r+r] - /// operation. - bool SelectAddr(SDValue Addr, SDValue &Op1, SDValue &Op2); - - /// InstructionSelect - This callback is invoked by - /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(); - - virtual const char *getPassName() const { - return "IA64 (Itanium) DAG->DAG Instruction Selector"; - } - -// Include the pieces autogenerated from the target description. -#include "IA64GenDAGISel.inc" - -private: - SDNode *SelectDIV(SDValue Op); - }; -} - -/// InstructionSelect - This callback is invoked by -/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void IA64DAGToDAGISel::InstructionSelect() { - DEBUG(BB->dump()); - - // Select target instructions for the DAG. - SelectRoot(*CurDAG); - CurDAG->RemoveDeadNodes(); -} - -SDNode *IA64DAGToDAGISel::SelectDIV(SDValue Op) { - SDNode *N = Op.getNode(); - SDValue Chain = N->getOperand(0); - SDValue Tmp1 = N->getOperand(0); - SDValue Tmp2 = N->getOperand(1); - DebugLoc dl = N->getDebugLoc(); - - bool isFP=false; - - if(Tmp1.getValueType().isFloatingPoint()) - isFP=true; - - bool isModulus=false; // is it a division or a modulus? - bool isSigned=false; - - switch(N->getOpcode()) { - case ISD::FDIV: - case ISD::SDIV: isModulus=false; isSigned=true; break; - case ISD::UDIV: isModulus=false; isSigned=false; break; - case ISD::FREM: - case ISD::SREM: isModulus=true; isSigned=true; break; - case ISD::UREM: isModulus=true; isSigned=false; break; - } - - // TODO: check for integer divides by powers of 2 (or other simple patterns?) - - SDValue TmpPR, TmpPR2; - SDValue TmpF1, TmpF2, TmpF3, TmpF4, TmpF5, TmpF6, TmpF7, TmpF8; - SDValue TmpF9, TmpF10,TmpF11,TmpF12,TmpF13,TmpF14,TmpF15; - SDNode *Result; - - // we'll need copies of F0 and F1 - SDValue F0 = CurDAG->getRegister(IA64::F0, MVT::f64); - SDValue F1 = CurDAG->getRegister(IA64::F1, MVT::f64); - - // OK, emit some code: - - if(!isFP) { - // first, load the inputs into FP regs. - TmpF1 = - SDValue(CurDAG->getTargetNode(IA64::SETFSIG, dl, MVT::f64, Tmp1), 0); - Chain = TmpF1.getValue(1); - TmpF2 = - SDValue(CurDAG->getTargetNode(IA64::SETFSIG, dl, MVT::f64, Tmp2), 0); - Chain = TmpF2.getValue(1); - - // next, convert the inputs to FP - if(isSigned) { - TmpF3 = - SDValue(CurDAG->getTargetNode(IA64::FCVTXF, dl, MVT::f64, TmpF1), 0); - Chain = TmpF3.getValue(1); - TmpF4 = - SDValue(CurDAG->getTargetNode(IA64::FCVTXF, dl, MVT::f64, TmpF2), 0); - Chain = TmpF4.getValue(1); - } else { // is unsigned - TmpF3 = - SDValue(CurDAG->getTargetNode(IA64::FCVTXUFS1, dl, MVT::f64, TmpF1), - 0); - Chain = TmpF3.getValue(1); - TmpF4 = - SDValue(CurDAG->getTargetNode(IA64::FCVTXUFS1, dl, MVT::f64, TmpF2), - 0); - Chain = TmpF4.getValue(1); - } - - } else { // this is an FP divide/remainder, so we 'leak' some temp - // regs and assign TmpF3=Tmp1, TmpF4=Tmp2 - TmpF3=Tmp1; - TmpF4=Tmp2; - } - - // we start by computing an approximate reciprocal (good to 9 bits?) - // note, this instruction writes _both_ TmpF5 (answer) and TmpPR (predicate) - if(isFP) - TmpF5 = SDValue(CurDAG->getTargetNode(IA64::FRCPAS0, dl, MVT::f64, - MVT::i1, TmpF3, TmpF4), 0); - else - TmpF5 = SDValue(CurDAG->getTargetNode(IA64::FRCPAS1, dl, MVT::f64, - MVT::i1, TmpF3, TmpF4), 0); - - TmpPR = TmpF5.getValue(1); - Chain = TmpF5.getValue(2); - - SDValue minusB; - if(isModulus) { // for remainders, it'll be handy to have - // copies of -input_b - minusB = SDValue(CurDAG->getTargetNode(IA64::SUB, dl, MVT::i64, - CurDAG->getRegister(IA64::r0, MVT::i64), Tmp2), 0); - Chain = minusB.getValue(1); - } - - SDValue TmpE0, TmpY1, TmpE1, TmpY2; - - SDValue OpsE0[] = { TmpF4, TmpF5, F1, TmpPR }; - TmpE0 = SDValue(CurDAG->getTargetNode(IA64::CFNMAS1, dl, MVT::f64, - OpsE0, 4), 0); - Chain = TmpE0.getValue(1); - SDValue OpsY1[] = { TmpF5, TmpE0, TmpF5, TmpPR }; - TmpY1 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64, - OpsY1, 4), 0); - Chain = TmpY1.getValue(1); - SDValue OpsE1[] = { TmpE0, TmpE0, F0, TmpPR }; - TmpE1 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64, - OpsE1, 4), 0); - Chain = TmpE1.getValue(1); - SDValue OpsY2[] = { TmpY1, TmpE1, TmpY1, TmpPR }; - TmpY2 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64, - OpsY2, 4), 0); - Chain = TmpY2.getValue(1); - - if(isFP) { // if this is an FP divide, we finish up here and exit early - if(isModulus) - assert(0 && "Sorry, try another FORTRAN compiler."); - - SDValue TmpE2, TmpY3, TmpQ0, TmpR0; - - SDValue OpsE2[] = { TmpE1, TmpE1, F0, TmpPR }; - TmpE2 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64, - OpsE2, 4), 0); - Chain = TmpE2.getValue(1); - SDValue OpsY3[] = { TmpY2, TmpE2, TmpY2, TmpPR }; - TmpY3 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64, - OpsY3, 4), 0); - Chain = TmpY3.getValue(1); - SDValue OpsQ0[] = { Tmp1, TmpY3, F0, TmpPR }; - TmpQ0 = - SDValue(CurDAG->getTargetNode(IA64::CFMADS1, dl, // double prec! - MVT::f64, OpsQ0, 4), 0); - Chain = TmpQ0.getValue(1); - SDValue OpsR0[] = { Tmp2, TmpQ0, Tmp1, TmpPR }; - TmpR0 = - SDValue(CurDAG->getTargetNode(IA64::CFNMADS1, dl, // double prec! - MVT::f64, OpsR0, 4), 0); - Chain = TmpR0.getValue(1); - -// we want Result to have the same target register as the frcpa, so -// we two-address hack it. See the comment "for this to work..." on -// page 48 of Intel application note #245415 - SDValue Ops[] = { TmpF5, TmpY3, TmpR0, TmpQ0, TmpPR }; - Result = CurDAG->getTargetNode(IA64::TCFMADS0, dl, // d.p. s0 rndg! - MVT::f64, Ops, 5); - Chain = SDValue(Result, 1); - return Result; // XXX: early exit! - } else { // this is *not* an FP divide, so there's a bit left to do: - - SDValue TmpQ2, TmpR2, TmpQ3, TmpQ; - - SDValue OpsQ2[] = { TmpF3, TmpY2, F0, TmpPR }; - TmpQ2 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64, - OpsQ2, 4), 0); - Chain = TmpQ2.getValue(1); - SDValue OpsR2[] = { TmpF4, TmpQ2, TmpF3, TmpPR }; - TmpR2 = SDValue(CurDAG->getTargetNode(IA64::CFNMAS1, dl, MVT::f64, - OpsR2, 4), 0); - Chain = TmpR2.getValue(1); - -// we want TmpQ3 to have the same target register as the frcpa? maybe we -// should two-address hack it. See the comment "for this to work..." on page -// 48 of Intel application note #245415 - SDValue OpsQ3[] = { TmpF5, TmpR2, TmpY2, TmpQ2, TmpPR }; - TmpQ3 = SDValue(CurDAG->getTargetNode(IA64::TCFMAS1, dl, MVT::f64, - OpsQ3, 5), 0); - Chain = TmpQ3.getValue(1); - - // STORY: without these two-address instructions (TCFMAS1 and TCFMADS0) - // the FPSWA won't be able to help out in the case of large/tiny - // arguments. Other fun bugs may also appear, e.g. 0/x = x, not 0. - - if(isSigned) - TmpQ = SDValue(CurDAG->getTargetNode(IA64::FCVTFXTRUNCS1, dl, - MVT::f64, TmpQ3), 0); - else - TmpQ = SDValue(CurDAG->getTargetNode(IA64::FCVTFXUTRUNCS1, dl, - MVT::f64, TmpQ3), 0); - - Chain = TmpQ.getValue(1); - - if(isModulus) { - SDValue FPminusB = - SDValue(CurDAG->getTargetNode(IA64::SETFSIG, dl, MVT::f64, minusB), - 0); - Chain = FPminusB.getValue(1); - SDValue Remainder = - SDValue(CurDAG->getTargetNode(IA64::XMAL, dl, MVT::f64, - TmpQ, FPminusB, TmpF1), 0); - Chain = Remainder.getValue(1); - Result = CurDAG->getTargetNode(IA64::GETFSIG, dl, MVT::i64, Remainder); - Chain = SDValue(Result, 1); - } else { // just an integer divide - Result = CurDAG->getTargetNode(IA64::GETFSIG, dl, MVT::i64, TmpQ); - Chain = SDValue(Result, 1); - } - - return Result; - } // wasn't an FP divide -} - -// Select - Convert the specified operand from a target-independent to a -// target-specific node if it hasn't already been changed. -SDNode *IA64DAGToDAGISel::Select(SDValue Op) { - SDNode *N = Op.getNode(); - if (N->isMachineOpcode()) - return NULL; // Already selected. - DebugLoc dl = Op.getDebugLoc(); - - switch (N->getOpcode()) { - default: break; - - case IA64ISD::BRCALL: { // XXX: this is also a hack! - SDValue Chain = N->getOperand(0); - SDValue InFlag; // Null incoming flag value. - - if(N->getNumOperands()==3) { // we have an incoming chain, callee and flag - InFlag = N->getOperand(2); - } - - unsigned CallOpcode; - SDValue CallOperand; - - // if we can call directly, do so - if (GlobalAddressSDNode *GASD = - dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) { - CallOpcode = IA64::BRCALL_IPREL_GA; - CallOperand = CurDAG->getTargetGlobalAddress(GASD->getGlobal(), MVT::i64); - } else if (isa<ExternalSymbolSDNode>(N->getOperand(1))) { - // FIXME: we currently NEED this case for correctness, to avoid - // "non-pic code with imm reloc.n against dynamic symbol" errors - CallOpcode = IA64::BRCALL_IPREL_ES; - CallOperand = N->getOperand(1); - } else { - // otherwise we need to load the function descriptor, - // load the branch target (function)'s entry point and GP, - // branch (call) then restore the GP - SDValue FnDescriptor = N->getOperand(1); - - // load the branch target's entry point [mem] and - // GP value [mem+8] - SDValue targetEntryPoint= - SDValue(CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64, MVT::Other, - FnDescriptor, CurDAG->getEntryNode()), 0); - Chain = targetEntryPoint.getValue(1); - SDValue targetGPAddr= - SDValue(CurDAG->getTargetNode(IA64::ADDS, dl, MVT::i64, - FnDescriptor, - CurDAG->getConstant(8, MVT::i64)), 0); - Chain = targetGPAddr.getValue(1); - SDValue targetGP = - SDValue(CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64,MVT::Other, - targetGPAddr, CurDAG->getEntryNode()), 0); - Chain = targetGP.getValue(1); - - Chain = CurDAG->getCopyToReg(Chain, dl, IA64::r1, targetGP, InFlag); - InFlag = Chain.getValue(1); - Chain = CurDAG->getCopyToReg(Chain, dl, IA64::B6, - targetEntryPoint, InFlag); // FLAG these? - InFlag = Chain.getValue(1); - - CallOperand = CurDAG->getRegister(IA64::B6, MVT::i64); - CallOpcode = IA64::BRCALL_INDIRECT; - } - - // Finally, once everything is setup, emit the call itself - if (InFlag.getNode()) - Chain = SDValue(CurDAG->getTargetNode(CallOpcode, dl, MVT::Other, - MVT::Flag, CallOperand, InFlag), 0); - else // there might be no arguments - Chain = SDValue(CurDAG->getTargetNode(CallOpcode, dl, MVT::Other, - MVT::Flag, CallOperand, Chain), 0); - InFlag = Chain.getValue(1); - - std::vector<SDValue> CallResults; - - CallResults.push_back(Chain); - CallResults.push_back(InFlag); - - for (unsigned i = 0, e = CallResults.size(); i != e; ++i) - ReplaceUses(Op.getValue(i), CallResults[i]); - return NULL; - } - - case IA64ISD::GETFD: { - SDValue Input = N->getOperand(0); - return CurDAG->getTargetNode(IA64::GETFD, dl, MVT::i64, Input); - } - - case ISD::FDIV: - case ISD::SDIV: - case ISD::UDIV: - case ISD::SREM: - case ISD::UREM: - return SelectDIV(Op); - - case ISD::TargetConstantFP: { - SDValue Chain = CurDAG->getEntryNode(); // this is a constant, so.. - - SDValue V; - ConstantFPSDNode* N2 = cast<ConstantFPSDNode>(N); - if (N2->getValueAPF().isPosZero()) { - V = CurDAG->getCopyFromReg(Chain, dl, IA64::F0, MVT::f64); - } else if (N2->isExactlyValue(N2->getValueType(0) == MVT::f32 ? - APFloat(+1.0f) : APFloat(+1.0))) { - V = CurDAG->getCopyFromReg(Chain, dl, IA64::F1, MVT::f64); - } else - assert(0 && "Unexpected FP constant!"); - - ReplaceUses(SDValue(N, 0), V); - return 0; - } - - case ISD::FrameIndex: { // TODO: reduce creepyness - int FI = cast<FrameIndexSDNode>(N)->getIndex(); - if (N->hasOneUse()) - return CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64, - CurDAG->getTargetFrameIndex(FI, MVT::i64)); - else - return CurDAG->getTargetNode(IA64::MOV, dl, MVT::i64, - CurDAG->getTargetFrameIndex(FI, MVT::i64)); - } - - case ISD::ConstantPool: { // TODO: nuke the constant pool - // (ia64 doesn't need one) - ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N); - Constant *C = CP->getConstVal(); - SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64, - CP->getAlignment()); - return CurDAG->getTargetNode(IA64::ADDL_GA, dl, MVT::i64, // ? - CurDAG->getRegister(IA64::r1, MVT::i64), CPI); - } - - case ISD::GlobalAddress: { - GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal(); - SDValue GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64); - SDValue Tmp = - SDValue(CurDAG->getTargetNode(IA64::ADDL_GA, dl, MVT::i64, - CurDAG->getRegister(IA64::r1, - MVT::i64), GA), 0); - return CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64, MVT::Other, Tmp, - CurDAG->getEntryNode()); - } - -/* XXX - case ISD::ExternalSymbol: { - SDValue EA = CurDAG->getTargetExternalSymbol( - cast<ExternalSymbolSDNode>(N)->getSymbol(), - MVT::i64); - SDValue Tmp = CurDAG->getTargetNode(IA64::ADDL_EA, dl, MVT::i64, - CurDAG->getRegister(IA64::r1, - MVT::i64), - EA); - return CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64, Tmp); - } -*/ - - case ISD::LOAD: { // FIXME: load -1, not 1, for bools? - LoadSDNode *LD = cast<LoadSDNode>(N); - SDValue Chain = LD->getChain(); - SDValue Address = LD->getBasePtr(); - - MVT TypeBeingLoaded = LD->getMemoryVT(); - unsigned Opc; - switch (TypeBeingLoaded.getSimpleVT()) { - default: -#ifndef NDEBUG - N->dump(CurDAG); -#endif - assert(0 && "Cannot load this type!"); - case MVT::i1: { // this is a bool - Opc = IA64::LD1; // first we load a byte, then compare for != 0 - if(N->getValueType(0) == MVT::i1) { // XXX: early exit! - return CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other, - SDValue(CurDAG->getTargetNode(Opc, dl, - MVT::i64, - Address), 0), - CurDAG->getRegister(IA64::r0, MVT::i64), - Chain); - } - /* otherwise, we want to load a bool into something bigger: LD1 - will do that for us, so we just fall through */ - } - case MVT::i8: Opc = IA64::LD1; break; - case MVT::i16: Opc = IA64::LD2; break; - case MVT::i32: Opc = IA64::LD4; break; - case MVT::i64: Opc = IA64::LD8; break; - - case MVT::f32: Opc = IA64::LDF4; break; - case MVT::f64: Opc = IA64::LDF8; break; - } - - // TODO: comment this - return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, - Address, Chain); - } - - case ISD::STORE: { - StoreSDNode *ST = cast<StoreSDNode>(N); - SDValue Address = ST->getBasePtr(); - SDValue Chain = ST->getChain(); - - unsigned Opc; - if (ISD::isNON_TRUNCStore(N)) { - switch (N->getOperand(1).getValueType().getSimpleVT()) { - default: assert(0 && "unknown type in store"); - case MVT::i1: { // this is a bool - Opc = IA64::ST1; // we store either 0 or 1 as a byte - // first load zero! - SDValue Initial = CurDAG->getCopyFromReg(Chain, dl, IA64::r0, MVT::i64); - Chain = Initial.getValue(1); - // then load 1 into the same reg iff the predicate to store is 1 - SDValue Tmp = ST->getValue(); - Tmp = - SDValue(CurDAG->getTargetNode(IA64::TPCADDS, dl, MVT::i64, Initial, - CurDAG->getTargetConstant(1, - MVT::i64), - Tmp), 0); - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, Tmp, Chain); - } - case MVT::i64: Opc = IA64::ST8; break; - case MVT::f64: Opc = IA64::STF8; break; - } - } else { // Truncating store - switch(ST->getMemoryVT().getSimpleVT()) { - default: assert(0 && "unknown type in truncstore"); - case MVT::i8: Opc = IA64::ST1; break; - case MVT::i16: Opc = IA64::ST2; break; - case MVT::i32: Opc = IA64::ST4; break; - case MVT::f32: Opc = IA64::STF4; break; - } - } - - SDValue N1 = N->getOperand(1); - SDValue N2 = N->getOperand(2); - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain); - } - - case ISD::BRCOND: { - SDValue Chain = N->getOperand(0); - SDValue CC = N->getOperand(1); - MachineBasicBlock *Dest = - cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock(); - //FIXME - we do NOT need long branches all the time - return CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC, - CurDAG->getBasicBlock(Dest), Chain); - } - - case ISD::CALLSEQ_START: - case ISD::CALLSEQ_END: { - int64_t Amt = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); - unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ? - IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP; - SDValue N0 = N->getOperand(0); - return CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0); - } - - case ISD::BR: - // FIXME: we don't need long branches all the time! - SDValue N0 = N->getOperand(0); - return CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other, - N->getOperand(1), N0); - } - - return SelectCode(Op); -} - - -/// createIA64DAGToDAGInstructionSelector - This pass converts a legalized DAG -/// into an IA64-specific DAG, ready for instruction scheduling. -/// -FunctionPass -*llvm::createIA64DAGToDAGInstructionSelector(IA64TargetMachine &TM) { - return new IA64DAGToDAGISel(TM); -} - diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp deleted file mode 100644 index c622345..0000000 --- a/lib/Target/IA64/IA64ISelLowering.cpp +++ /dev/null @@ -1,632 +0,0 @@ -//===-- IA64ISelLowering.cpp - IA64 DAG Lowering Implementation -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the IA64ISelLowering class. -// -//===----------------------------------------------------------------------===// - -#include "IA64ISelLowering.h" -#include "IA64MachineFunctionInfo.h" -#include "IA64TargetMachine.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Constants.h" -#include "llvm/Function.h" -using namespace llvm; - -IA64TargetLowering::IA64TargetLowering(TargetMachine &TM) - : TargetLowering(TM) { - - // register class for general registers - addRegisterClass(MVT::i64, IA64::GRRegisterClass); - - // register class for FP registers - addRegisterClass(MVT::f64, IA64::FPRegisterClass); - - // register class for predicate registers - addRegisterClass(MVT::i1, IA64::PRRegisterClass); - - setLoadExtAction(ISD::EXTLOAD , MVT::i1 , Promote); - - setLoadExtAction(ISD::ZEXTLOAD , MVT::i1 , Promote); - - setLoadExtAction(ISD::SEXTLOAD , MVT::i1 , Promote); - setLoadExtAction(ISD::SEXTLOAD , MVT::i8 , Expand); - setLoadExtAction(ISD::SEXTLOAD , MVT::i16 , Expand); - setLoadExtAction(ISD::SEXTLOAD , MVT::i32 , Expand); - - setOperationAction(ISD::BRIND , MVT::Other, Expand); - setOperationAction(ISD::BR_JT , MVT::Other, Expand); - setOperationAction(ISD::BR_CC , MVT::Other, Expand); - setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); - - // ia64 uses SELECT not SELECT_CC - setOperationAction(ISD::SELECT_CC , MVT::Other, Expand); - - // We need to handle ISD::RET for void functions ourselves, - // so we get a chance to restore ar.pfs before adding a - // br.ret insn - setOperationAction(ISD::RET, MVT::Other, Custom); - - setShiftAmountType(MVT::i64); - - setOperationAction(ISD::FREM , MVT::f32 , Expand); - setOperationAction(ISD::FREM , MVT::f64 , Expand); - - setOperationAction(ISD::UREM , MVT::f32 , Expand); - setOperationAction(ISD::UREM , MVT::f64 , Expand); - - setOperationAction(ISD::MEMBARRIER , MVT::Other, Expand); - - setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); - setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); - - // We don't support sin/cos/sqrt/pow - setOperationAction(ISD::FSIN , MVT::f64, Expand); - setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FSQRT, MVT::f64, Expand); - setOperationAction(ISD::FPOW , MVT::f64, Expand); - setOperationAction(ISD::FSIN , MVT::f32, Expand); - setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FSQRT, MVT::f32, Expand); - setOperationAction(ISD::FPOW , MVT::f32, Expand); - - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); - - // FIXME: IA64 supports fcopysign natively! - setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); - setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); - - // We don't have line number support yet. - setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); - setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); - setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand); - setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); - - // IA64 has ctlz in the form of the 'fnorm' instruction. The Legalizer - // expansion for ctlz/cttz in terms of ctpop is much larger, but lower - // latency. - // FIXME: Custom lower CTLZ when compiling for size? - setOperationAction(ISD::CTLZ , MVT::i64 , Expand); - setOperationAction(ISD::CTTZ , MVT::i64 , Expand); - setOperationAction(ISD::ROTL , MVT::i64 , Expand); - setOperationAction(ISD::ROTR , MVT::i64 , Expand); - - // FIXME: IA64 has this, but is not implemented. should be mux @rev - setOperationAction(ISD::BSWAP, MVT::i64 , Expand); - - // VASTART needs to be custom lowered to use the VarArgsFrameIndex - setOperationAction(ISD::VAARG , MVT::Other, Custom); - setOperationAction(ISD::VASTART , MVT::Other, Custom); - - // FIXME: These should be legal - setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand); - setOperationAction(ISD::BIT_CONVERT, MVT::f64, Expand); - - // Use the default implementation. - setOperationAction(ISD::VACOPY , MVT::Other, Expand); - setOperationAction(ISD::VAEND , MVT::Other, Expand); - setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); - setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); - - // Thread Local Storage - setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); - - setStackPointerRegisterToSaveRestore(IA64::r12); - - setJumpBufSize(704); // on ia64-linux, jmp_bufs are 704 bytes.. - setJumpBufAlignment(16); // ...and must be 16-byte aligned - - computeRegisterProperties(); - - addLegalFPImmediate(APFloat(+0.0)); - addLegalFPImmediate(APFloat(-0.0)); - addLegalFPImmediate(APFloat(+1.0)); - addLegalFPImmediate(APFloat(-1.0)); -} - -const char *IA64TargetLowering::getTargetNodeName(unsigned Opcode) const { - switch (Opcode) { - default: return 0; - case IA64ISD::GETFD: return "IA64ISD::GETFD"; - case IA64ISD::BRCALL: return "IA64ISD::BRCALL"; - case IA64ISD::RET_FLAG: return "IA64ISD::RET_FLAG"; - } -} - -MVT IA64TargetLowering::getSetCCResultType(MVT VT) const { - return MVT::i1; -} - -/// getFunctionAlignment - Return the Log2 alignment of this function. -unsigned IA64TargetLowering::getFunctionAlignment(const Function *) const { - return 5; -} - -void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &ArgValues, - DebugLoc dl) { - // - // add beautiful description of IA64 stack frame format - // here (from intel 24535803.pdf most likely) - // - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); - - GP = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); - SP = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); - RP = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); - - MachineBasicBlock& BB = MF.front(); - - unsigned args_int[] = {IA64::r32, IA64::r33, IA64::r34, IA64::r35, - IA64::r36, IA64::r37, IA64::r38, IA64::r39}; - - unsigned args_FP[] = {IA64::F8, IA64::F9, IA64::F10, IA64::F11, - IA64::F12,IA64::F13,IA64::F14, IA64::F15}; - - unsigned argVreg[8]; - unsigned argPreg[8]; - unsigned argOpc[8]; - - unsigned used_FPArgs = 0; // how many FP args have been used so far? - - unsigned ArgOffset = 0; - int count = 0; - - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) - { - SDValue newroot, argt; - if(count < 8) { // need to fix this logic? maybe. - - switch (getValueType(I->getType()).getSimpleVT()) { - default: - assert(0 && "ERROR in LowerArgs: can't lower this type of arg.\n"); - case MVT::f32: - // fixme? (well, will need to for weird FP structy stuff, - // see intel ABI docs) - case MVT::f64: -//XXX BuildMI(&BB, IA64::IDEF, 0, args_FP[used_FPArgs]); - MF.getRegInfo().addLiveIn(args_FP[used_FPArgs]); - // mark this reg as liveIn - // floating point args go into f8..f15 as-needed, the increment - argVreg[count] = // is below..: - MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::f64)); - // FP args go into f8..f15 as needed: (hence the ++) - argPreg[count] = args_FP[used_FPArgs++]; - argOpc[count] = IA64::FMOV; - argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), dl, - argVreg[count], MVT::f64); - if (I->getType() == Type::FloatTy) - argt = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, argt, - DAG.getIntPtrConstant(0)); - break; - case MVT::i1: // NOTE: as far as C abi stuff goes, - // bools are just boring old ints - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: -//XXX BuildMI(&BB, IA64::IDEF, 0, args_int[count]); - MF.getRegInfo().addLiveIn(args_int[count]); - // mark this register as liveIn - argVreg[count] = - MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); - argPreg[count] = args_int[count]; - argOpc[count] = IA64::MOV; - argt = newroot = - DAG.getCopyFromReg(DAG.getRoot(), dl, argVreg[count], MVT::i64); - if ( getValueType(I->getType()) != MVT::i64) - argt = DAG.getNode(ISD::TRUNCATE, dl, getValueType(I->getType()), - newroot); - break; - } - } else { // more than 8 args go into the frame - // Create the frame index object for this incoming parameter... - ArgOffset = 16 + 8 * (count - 8); - int FI = MFI->CreateFixedObject(8, ArgOffset); - - // Create the SelectionDAG nodes corresponding to a load - //from this parameter - SDValue FIN = DAG.getFrameIndex(FI, MVT::i64); - argt = newroot = DAG.getLoad(getValueType(I->getType()), dl, - DAG.getEntryNode(), FIN, NULL, 0); - } - ++count; - DAG.setRoot(newroot.getValue(1)); - ArgValues.push_back(argt); - } - - - // Create a vreg to hold the output of (what will become) - // the "alloc" instruction - VirtGPR = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); - BuildMI(&BB, dl, TII->get(IA64::PSEUDO_ALLOC), VirtGPR); - // we create a PSEUDO_ALLOC (pseudo)instruction for now -/* - BuildMI(&BB, IA64::IDEF, 0, IA64::r1); - - // hmm: - BuildMI(&BB, IA64::IDEF, 0, IA64::r12); - BuildMI(&BB, IA64::IDEF, 0, IA64::rp); - // ..hmm. - - BuildMI(&BB, IA64::MOV, 1, GP).addReg(IA64::r1); - - // hmm: - BuildMI(&BB, IA64::MOV, 1, SP).addReg(IA64::r12); - BuildMI(&BB, IA64::MOV, 1, RP).addReg(IA64::rp); - // ..hmm. -*/ - - unsigned tempOffset=0; - - // if this is a varargs function, we simply lower llvm.va_start by - // pointing to the first entry - if(F.isVarArg()) { - tempOffset=0; - VarArgsFrameIndex = MFI->CreateFixedObject(8, tempOffset); - } - - // here we actually do the moving of args, and store them to the stack - // too if this is a varargs function: - for (int i = 0; i < count && i < 8; ++i) { - BuildMI(&BB, dl, TII->get(argOpc[i]), argVreg[i]).addReg(argPreg[i]); - if(F.isVarArg()) { - // if this is a varargs function, we copy the input registers to the stack - int FI = MFI->CreateFixedObject(8, tempOffset); - tempOffset+=8; //XXX: is it safe to use r22 like this? - BuildMI(&BB, dl, TII->get(IA64::MOV), IA64::r22).addFrameIndex(FI); - // FIXME: we should use st8.spill here, one day - BuildMI(&BB, dl, TII->get(IA64::ST8), IA64::r22).addReg(argPreg[i]); - } - } - - // Finally, inform the code generator which regs we return values in. - // (see the ISD::RET: case in the instruction selector) - switch (getValueType(F.getReturnType()).getSimpleVT()) { - default: assert(0 && "i have no idea where to return this type!"); - case MVT::isVoid: break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - MF.getRegInfo().addLiveOut(IA64::r8); - break; - case MVT::f32: - case MVT::f64: - MF.getRegInfo().addLiveOut(IA64::F8); - break; - } -} - -std::pair<SDValue, SDValue> -IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, - bool RetSExt, bool RetZExt, bool isVarArg, - bool isInreg, unsigned NumFixedArgs, - unsigned CallingConv, - bool isTailCall, SDValue Callee, - ArgListTy &Args, SelectionDAG &DAG, - DebugLoc dl) { - - MachineFunction &MF = DAG.getMachineFunction(); - - unsigned NumBytes = 16; - unsigned outRegsUsed = 0; - - if (Args.size() > 8) { - NumBytes += (Args.size() - 8) * 8; - outRegsUsed = 8; - } else { - outRegsUsed = Args.size(); - } - - // FIXME? this WILL fail if we ever try to pass around an arg that - // consumes more than a single output slot (a 'real' double, int128 - // some sort of aggregate etc.), as we'll underestimate how many 'outX' - // registers we use. Hopefully, the assembler will notice. - MF.getInfo<IA64FunctionInfo>()->outRegsUsed= - std::max(outRegsUsed, MF.getInfo<IA64FunctionInfo>()->outRegsUsed); - - // keep stack frame 16-byte aligned - // assert(NumBytes==((NumBytes+15) & ~15) && - // "stack frame not 16-byte aligned!"); - NumBytes = (NumBytes+15) & ~15; - - Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); - - SDValue StackPtr; - std::vector<SDValue> Stores; - std::vector<SDValue> Converts; - std::vector<SDValue> RegValuesToPass; - unsigned ArgOffset = 16; - - for (unsigned i = 0, e = Args.size(); i != e; ++i) - { - SDValue Val = Args[i].Node; - MVT ObjectVT = Val.getValueType(); - SDValue ValToStore(0, 0), ValToConvert(0, 0); - unsigned ObjSize=8; - switch (ObjectVT.getSimpleVT()) { - default: assert(0 && "unexpected argument type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: { - //promote to 64-bits, sign/zero extending based on type - //of the argument - ISD::NodeType ExtendKind = ISD::ANY_EXTEND; - if (Args[i].isSExt) - ExtendKind = ISD::SIGN_EXTEND; - else if (Args[i].isZExt) - ExtendKind = ISD::ZERO_EXTEND; - Val = DAG.getNode(ExtendKind, dl, MVT::i64, Val); - // XXX: fall through - } - case MVT::i64: - //ObjSize = 8; - if(RegValuesToPass.size() >= 8) { - ValToStore = Val; - } else { - RegValuesToPass.push_back(Val); - } - break; - case MVT::f32: - //promote to 64-bits - Val = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Val); - // XXX: fall through - case MVT::f64: - if(RegValuesToPass.size() >= 8) { - ValToStore = Val; - } else { - RegValuesToPass.push_back(Val); - if(1 /* TODO: if(calling external or varadic function)*/ ) { - ValToConvert = Val; // additionally pass this FP value as an int - } - } - break; - } - - if(ValToStore.getNode()) { - if(!StackPtr.getNode()) { - StackPtr = DAG.getRegister(IA64::r12, MVT::i64); - } - SDValue PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i64, StackPtr, PtrOff); - Stores.push_back(DAG.getStore(Chain, dl, ValToStore, PtrOff, NULL, 0)); - ArgOffset += ObjSize; - } - - if(ValToConvert.getNode()) { - Converts.push_back(DAG.getNode(IA64ISD::GETFD, dl, - MVT::i64, ValToConvert)); - } - } - - // Emit all stores, make sure they occur before any copies into physregs. - if (!Stores.empty()) - Chain = DAG.getNode(ISD::TokenFactor, dl, - MVT::Other, &Stores[0],Stores.size()); - - static const unsigned IntArgRegs[] = { - IA64::out0, IA64::out1, IA64::out2, IA64::out3, - IA64::out4, IA64::out5, IA64::out6, IA64::out7 - }; - - static const unsigned FPArgRegs[] = { - IA64::F8, IA64::F9, IA64::F10, IA64::F11, - IA64::F12, IA64::F13, IA64::F14, IA64::F15 - }; - - SDValue InFlag; - - // save the current GP, SP and RP : FIXME: do we need to do all 3 always? - SDValue GPBeforeCall = DAG.getCopyFromReg(Chain, dl, IA64::r1, - MVT::i64, InFlag); - Chain = GPBeforeCall.getValue(1); - InFlag = Chain.getValue(2); - SDValue SPBeforeCall = DAG.getCopyFromReg(Chain, dl, IA64::r12, - MVT::i64, InFlag); - Chain = SPBeforeCall.getValue(1); - InFlag = Chain.getValue(2); - SDValue RPBeforeCall = DAG.getCopyFromReg(Chain, dl, IA64::rp, - MVT::i64, InFlag); - Chain = RPBeforeCall.getValue(1); - InFlag = Chain.getValue(2); - - // Build a sequence of copy-to-reg nodes chained together with token chain - // and flag operands which copy the outgoing integer args into regs out[0-7] - // mapped 1:1 and the FP args into regs F8-F15 "lazily" - // TODO: for performance, we should only copy FP args into int regs when we - // know this is required (i.e. for varardic or external (unknown) functions) - - // first to the FP->(integer representation) conversions, these are - // flagged for now, but shouldn't have to be (TODO) - unsigned seenConverts = 0; - for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) { - if(RegValuesToPass[i].getValueType().isFloatingPoint()) { - Chain = DAG.getCopyToReg(Chain, dl, IntArgRegs[i], - Converts[seenConverts++], InFlag); - InFlag = Chain.getValue(1); - } - } - - // next copy args into the usual places, these are flagged - unsigned usedFPArgs = 0; - for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) { - Chain = DAG.getCopyToReg(Chain, dl, - RegValuesToPass[i].getValueType().isInteger() ? - IntArgRegs[i] : FPArgRegs[usedFPArgs++], RegValuesToPass[i], InFlag); - InFlag = Chain.getValue(1); - } - - // If the callee is a GlobalAddress node (quite common, every direct call is) - // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. -/* - if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i64); - } -*/ - - std::vector<MVT> NodeTys; - std::vector<SDValue> CallOperands; - NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. - CallOperands.push_back(Chain); - CallOperands.push_back(Callee); - - // emit the call itself - if (InFlag.getNode()) - CallOperands.push_back(InFlag); - else - assert(0 && "this should never happen!\n"); - - // to make way for a hack: - Chain = DAG.getNode(IA64ISD::BRCALL, dl, NodeTys, - &CallOperands[0], CallOperands.size()); - InFlag = Chain.getValue(1); - - // restore the GP, SP and RP after the call - Chain = DAG.getCopyToReg(Chain, dl, IA64::r1, GPBeforeCall, InFlag); - InFlag = Chain.getValue(1); - Chain = DAG.getCopyToReg(Chain, dl, IA64::r12, SPBeforeCall, InFlag); - InFlag = Chain.getValue(1); - Chain = DAG.getCopyToReg(Chain, dl, IA64::rp, RPBeforeCall, InFlag); - InFlag = Chain.getValue(1); - - std::vector<MVT> RetVals; - RetVals.push_back(MVT::Other); - RetVals.push_back(MVT::Flag); - - MVT RetTyVT = getValueType(RetTy); - SDValue RetVal; - if (RetTyVT != MVT::isVoid) { - switch (RetTyVT.getSimpleVT()) { - default: assert(0 && "Unknown value type to return!"); - case MVT::i1: { // bools are just like other integers (returned in r8) - // we *could* fall through to the truncate below, but this saves a - // few redundant predicate ops - SDValue boolInR8 = DAG.getCopyFromReg(Chain, dl, IA64::r8, - MVT::i64,InFlag); - InFlag = boolInR8.getValue(2); - Chain = boolInR8.getValue(1); - SDValue zeroReg = DAG.getCopyFromReg(Chain, dl, IA64::r0, - MVT::i64, InFlag); - InFlag = zeroReg.getValue(2); - Chain = zeroReg.getValue(1); - - RetVal = DAG.getSetCC(dl, MVT::i1, boolInR8, zeroReg, ISD::SETNE); - break; - } - case MVT::i8: - case MVT::i16: - case MVT::i32: - RetVal = DAG.getCopyFromReg(Chain, dl, IA64::r8, MVT::i64, InFlag); - Chain = RetVal.getValue(1); - - // keep track of whether it is sign or zero extended (todo: bools?) -/* XXX - RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext, - dl, MVT::i64, RetVal, DAG.getValueType(RetTyVT)); -*/ - RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal); - break; - case MVT::i64: - RetVal = DAG.getCopyFromReg(Chain, dl, IA64::r8, MVT::i64, InFlag); - Chain = RetVal.getValue(1); - InFlag = RetVal.getValue(2); // XXX dead - break; - case MVT::f32: - RetVal = DAG.getCopyFromReg(Chain, dl, IA64::F8, MVT::f64, InFlag); - Chain = RetVal.getValue(1); - RetVal = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, RetVal, - DAG.getIntPtrConstant(0)); - break; - case MVT::f64: - RetVal = DAG.getCopyFromReg(Chain, dl, IA64::F8, MVT::f64, InFlag); - Chain = RetVal.getValue(1); - InFlag = RetVal.getValue(2); // XXX dead - break; - } - } - - Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), - DAG.getIntPtrConstant(0, true), SDValue()); - return std::make_pair(RetVal, Chain); -} - -SDValue IA64TargetLowering:: -LowerOperation(SDValue Op, SelectionDAG &DAG) { - DebugLoc dl = Op.getDebugLoc(); - switch (Op.getOpcode()) { - default: assert(0 && "Should not custom lower this!"); - case ISD::GlobalTLSAddress: - assert(0 && "TLS not implemented for IA64."); - case ISD::RET: { - SDValue AR_PFSVal, Copy; - - switch(Op.getNumOperands()) { - default: - assert(0 && "Do not know how to return this many arguments!"); - abort(); - case 1: - AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), dl, VirtGPR, MVT::i64); - AR_PFSVal = DAG.getCopyToReg(AR_PFSVal.getValue(1), dl, IA64::AR_PFS, - AR_PFSVal); - return DAG.getNode(IA64ISD::RET_FLAG, dl, MVT::Other, AR_PFSVal); - case 3: { - // Copy the result into the output register & restore ar.pfs - MVT ArgVT = Op.getOperand(1).getValueType(); - unsigned ArgReg = ArgVT.isInteger() ? IA64::r8 : IA64::F8; - - AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), dl, VirtGPR, MVT::i64); - Copy = DAG.getCopyToReg(AR_PFSVal.getValue(1), dl, ArgReg, - Op.getOperand(1), SDValue()); - AR_PFSVal = DAG.getCopyToReg(Copy.getValue(0), dl, - IA64::AR_PFS, AR_PFSVal, Copy.getValue(1)); - return DAG.getNode(IA64ISD::RET_FLAG, dl, MVT::Other, - AR_PFSVal, AR_PFSVal.getValue(1)); - } - } - return SDValue(); - } - case ISD::VAARG: { - MVT VT = getPointerTy(); - const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); - SDValue VAList = DAG.getLoad(VT, dl, Op.getOperand(0), Op.getOperand(1), - SV, 0); - // Increment the pointer, VAList, to the next vaarg - SDValue VAIncr = DAG.getNode(ISD::ADD, dl, VT, VAList, - DAG.getConstant(VT.getSizeInBits()/8, - VT)); - // Store the incremented VAList to the legalized pointer - VAIncr = DAG.getStore(VAList.getValue(1), dl, VAIncr, - Op.getOperand(1), SV, 0); - // Load the actual argument out of the pointer VAList - return DAG.getLoad(Op.getValueType(), dl, VAIncr, VAList, NULL, 0); - } - case ISD::VASTART: { - // vastart just stores the address of the VarArgsFrameIndex slot into the - // memory location argument. - SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); - const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); - return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0); - } - // Frame & Return address. Currently unimplemented - case ISD::RETURNADDR: break; - case ISD::FRAMEADDR: break; - } - return SDValue(); -} diff --git a/lib/Target/IA64/IA64ISelLowering.h b/lib/Target/IA64/IA64ISelLowering.h deleted file mode 100644 index b9c8bf2..0000000 --- a/lib/Target/IA64/IA64ISelLowering.h +++ /dev/null @@ -1,78 +0,0 @@ -//===-- IA64ISelLowering.h - IA64 DAG Lowering Interface --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interfaces that IA64 uses to lower LLVM code into a -// selection DAG. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_IA64_IA64ISELLOWERING_H -#define LLVM_TARGET_IA64_IA64ISELLOWERING_H - -#include "llvm/Target/TargetLowering.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "IA64.h" - -namespace llvm { - namespace IA64ISD { - enum NodeType { - // Start the numbering where the builting ops and target ops leave off. - FIRST_NUMBER = ISD::BUILTIN_OP_END, - - /// GETFD - the getf.d instruction takes a floating point operand and - /// returns its 64-bit memory representation as an i64 - GETFD, - - // TODO: explain this hack - BRCALL, - - // RET_FLAG - Return with a flag operand - RET_FLAG - }; - } - - class IA64TargetLowering : public TargetLowering { - int VarArgsFrameIndex; // FrameIndex for start of varargs area. - //int ReturnAddrIndex; // FrameIndex for return slot. - unsigned GP, SP, RP; // FIXME - clean this mess up - public: - explicit IA64TargetLowering(TargetMachine &TM); - - unsigned VirtGPR; // this is public so it can be accessed in the selector - // for ISD::RET. add an accessor instead? FIXME - const char *getTargetNodeName(unsigned Opcode) const; - - /// getSetCCResultType: return ISD::SETCC's result type. - virtual MVT getSetCCResultType(MVT VT) const; - - /// LowerArguments - This hook must be implemented to indicate how we should - /// lower the arguments for the specified function, into the specified DAG. - virtual void LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &ArgValues, - DebugLoc dl); - - /// LowerCallTo - This hook lowers an abstract call to a function into an - /// actual call. - virtual std::pair<SDValue, SDValue> - LowerCallTo(SDValue Chain, const Type *RetTy, - bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, - unsigned NumFixedArgs, unsigned CC, bool isTailCall, - SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, - DebugLoc dl); - - /// LowerOperation - for custom lowering specific ops - /// (currently, only "ret void") - virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - - /// getFunctionAlignment - Return the Log2 alignment of this function. - virtual unsigned getFunctionAlignment(const Function *F) const; - }; -} - -#endif // LLVM_TARGET_IA64_IA64ISELLOWERING_H diff --git a/lib/Target/IA64/IA64InstrBuilder.h b/lib/Target/IA64/IA64InstrBuilder.h deleted file mode 100644 index a5d4dca..0000000 --- a/lib/Target/IA64/IA64InstrBuilder.h +++ /dev/null @@ -1,40 +0,0 @@ -//===-- IA64PCInstrBuilder.h - Aids for building IA64 insts -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file exposes functions that may be used with BuildMI from the -// MachineInstrBuilder.h file to simplify generating frame and constant pool -// references. -// -//===----------------------------------------------------------------------===// - -#ifndef IA64_INSTRBUILDER_H -#define IA64_INSTRBUILDER_H - -#include "llvm/CodeGen/MachineInstrBuilder.h" - -namespace llvm { - -/// addFrameReference - This function is used to add a reference to the base of -/// an abstract object on the stack frame of the current function. This -/// reference has base register as the FrameIndex offset until it is resolved. -/// This allows a constant offset to be specified as well... -/// -inline const MachineInstrBuilder& -addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0, - bool mem = true) { - if (mem) - return MIB.addImm(Offset).addFrameIndex(FI); - else - return MIB.addFrameIndex(FI).addImm(Offset); -} - -} // End llvm namespace - -#endif - diff --git a/lib/Target/IA64/IA64InstrFormats.td b/lib/Target/IA64/IA64InstrFormats.td deleted file mode 100644 index c465880..0000000 --- a/lib/Target/IA64/IA64InstrFormats.td +++ /dev/null @@ -1,80 +0,0 @@ -//===- IA64InstrFormats.td - IA64 Instruction Formats --*- tablegen -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// - Warning: the stuff in here isn't really being used, so is mostly -// junk. It'll get fixed as the JIT gets built. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Instruction format superclass -//===----------------------------------------------------------------------===// - -class InstIA64<bits<4> op, dag OOL, dag IOL, string asmstr> : Instruction { - // IA64 instruction baseline - field bits<41> Inst; - let Namespace = "IA64"; - let OutOperandList = OOL; - let InOperandList = IOL; - let AsmString = asmstr; - - let Inst{40-37} = op; -} - -//"Each Itanium instruction is categorized into one of six types." -//We should have: -// A, I, M, F, B, L+X - -class AForm<bits<4> opcode, bits<6> qpReg, dag OOL, dag IOL, string asmstr> : - InstIA64<opcode, OOL, IOL, asmstr> { - - let Inst{5-0} = qpReg; -} - -class AForm_DAG<bits<4> opcode, bits<6> qpReg, dag OOL, dag IOL, string asmstr, - list<dag> pattern> : - InstIA64<opcode, OOL, IOL, asmstr> { - - let Pattern = pattern; - let Inst{5-0} = qpReg; -} - -let isBranch = 1, isTerminator = 1 in -class BForm<bits<4> opcode, bits<6> x6, bits<3> btype, dag OOL, dag IOL, string asmstr> : - InstIA64<opcode, OOL, IOL, asmstr> { - - let Inst{32-27} = x6; - let Inst{8-6} = btype; -} - -class MForm<bits<4> opcode, bits<6> x6, dag OOL, dag IOL, string asmstr> : - InstIA64<opcode, OOL, IOL, asmstr> { - bits<7> Ra; - bits<7> Rb; - bits<16> disp; - - let Inst{35-30} = x6; -// let Inst{20-16} = Rb; - let Inst{15-0} = disp; -} - -class RawForm<bits<4> opcode, bits<26> rest, dag OOL, dag IOL, string asmstr> : - InstIA64<opcode, OOL, IOL, asmstr> { - let Inst{25-0} = rest; -} - -// Pseudo instructions. -class PseudoInstIA64<dag OOL, dag IOL, string nm> : InstIA64<0, OOL, IOL, nm> { -} - -class PseudoInstIA64_DAG<dag OOL, dag IOL, string nm, list<dag> pattern> - : InstIA64<0, OOL, IOL, nm> { - let Pattern = pattern; -} - diff --git a/lib/Target/IA64/IA64InstrInfo.cpp b/lib/Target/IA64/IA64InstrInfo.cpp deleted file mode 100644 index 5f89d4f..0000000 --- a/lib/Target/IA64/IA64InstrInfo.cpp +++ /dev/null @@ -1,193 +0,0 @@ -//===- IA64InstrInfo.cpp - IA64 Instruction Information -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the IA64 implementation of the TargetInstrInfo class. -// -//===----------------------------------------------------------------------===// - -#include "IA64InstrInfo.h" -#include "IA64.h" -#include "IA64InstrBuilder.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/ADT/SmallVector.h" -#include "IA64GenInstrInfo.inc" -using namespace llvm; - -IA64InstrInfo::IA64InstrInfo() - : TargetInstrInfoImpl(IA64Insts, sizeof(IA64Insts)/sizeof(IA64Insts[0])), - RI(*this) { -} - - -bool IA64InstrInfo::isMoveInstr(const MachineInstr& MI, - unsigned& sourceReg, - unsigned& destReg, - unsigned& SrcSR, unsigned& DstSR) const { - SrcSR = DstSR = 0; // No sub-registers. - - unsigned oc = MI.getOpcode(); - if (oc == IA64::MOV || oc == IA64::FMOV) { - // TODO: this doesn't detect predicate moves - assert(MI.getNumOperands() >= 2 && - /* MI.getOperand(0).isReg() && - MI.getOperand(1).isReg() && */ - "invalid register-register move instruction"); - if (MI.getOperand(0).isReg() && - MI.getOperand(1).isReg()) { - // if both operands of the MOV/FMOV are registers, then - // yes, this is a move instruction - sourceReg = MI.getOperand(1).getReg(); - destReg = MI.getOperand(0).getReg(); - return true; - } - } - return false; // we don't consider e.g. %regN = MOV <FrameIndex #x> a - // move instruction -} - -unsigned -IA64InstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl<MachineOperand> &Cond)const { - // FIXME this should probably have a DebugLoc argument - DebugLoc dl = DebugLoc::getUnknownLoc(); - // Can only insert uncond branches so far. - assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); - BuildMI(&MBB, dl, get(IA64::BRL_NOTCALL)).addMBB(TBB); - return 1; -} - -bool IA64InstrInfo::copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *DestRC, - const TargetRegisterClass *SrcRC) const { - if (DestRC != SrcRC) { - // Not yet supported! - return false; - } - - DebugLoc DL = DebugLoc::getUnknownLoc(); - if (MI != MBB.end()) DL = MI->getDebugLoc(); - - if(DestRC == IA64::PRRegisterClass ) // if a bool, we use pseudocode - // (SrcReg) DestReg = cmp.eq.unc(r0, r0) - BuildMI(MBB, MI, DL, get(IA64::PCMPEQUNC), DestReg) - .addReg(IA64::r0).addReg(IA64::r0).addReg(SrcReg); - else // otherwise, MOV works (for both gen. regs and FP regs) - BuildMI(MBB, MI, DL, get(IA64::MOV), DestReg).addReg(SrcReg); - - return true; -} - -void IA64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, - int FrameIdx, - const TargetRegisterClass *RC) const{ - DebugLoc DL = DebugLoc::getUnknownLoc(); - if (MI != MBB.end()) DL = MI->getDebugLoc(); - - if (RC == IA64::FPRegisterClass) { - BuildMI(MBB, MI, DL, get(IA64::STF_SPILL)).addFrameIndex(FrameIdx) - .addReg(SrcReg, getKillRegState(isKill)); - } else if (RC == IA64::GRRegisterClass) { - BuildMI(MBB, MI, DL, get(IA64::ST8)).addFrameIndex(FrameIdx) - .addReg(SrcReg, getKillRegState(isKill)); - } else if (RC == IA64::PRRegisterClass) { - /* we use IA64::r2 as a temporary register for doing this hackery. */ - // first we load 0: - BuildMI(MBB, MI, DL, get(IA64::MOV), IA64::r2).addReg(IA64::r0); - // then conditionally add 1: - BuildMI(MBB, MI, DL, get(IA64::CADDIMM22), IA64::r2).addReg(IA64::r2) - .addImm(1).addReg(SrcReg, getKillRegState(isKill)); - // and then store it to the stack - BuildMI(MBB, MI, DL, get(IA64::ST8)) - .addFrameIndex(FrameIdx) - .addReg(IA64::r2); - } else assert(0 && - "sorry, I don't know how to store this sort of reg in the stack\n"); -} - -void IA64InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, - bool isKill, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const { - unsigned Opc = 0; - if (RC == IA64::FPRegisterClass) { - Opc = IA64::STF8; - } else if (RC == IA64::GRRegisterClass) { - Opc = IA64::ST8; - } else if (RC == IA64::PRRegisterClass) { - Opc = IA64::ST1; - } else { - assert(0 && - "sorry, I don't know how to store this sort of reg\n"); - } - - DebugLoc DL = DebugLoc::getUnknownLoc(); - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)); - for (unsigned i = 0, e = Addr.size(); i != e; ++i) - MIB.addOperand(Addr[i]); - MIB.addReg(SrcReg, getKillRegState(isKill)); - NewMIs.push_back(MIB); - return; - -} - -void IA64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx, - const TargetRegisterClass *RC)const{ - DebugLoc DL = DebugLoc::getUnknownLoc(); - if (MI != MBB.end()) DL = MI->getDebugLoc(); - - if (RC == IA64::FPRegisterClass) { - BuildMI(MBB, MI, DL, get(IA64::LDF_FILL), DestReg).addFrameIndex(FrameIdx); - } else if (RC == IA64::GRRegisterClass) { - BuildMI(MBB, MI, DL, get(IA64::LD8), DestReg).addFrameIndex(FrameIdx); - } else if (RC == IA64::PRRegisterClass) { - // first we load a byte from the stack into r2, our 'predicate hackery' - // scratch reg - BuildMI(MBB, MI, DL, get(IA64::LD8), IA64::r2).addFrameIndex(FrameIdx); - // then we compare it to zero. If it _is_ zero, compare-not-equal to - // r0 gives us 0, which is what we want, so that's nice. - BuildMI(MBB, MI, DL, get(IA64::CMPNE), DestReg) - .addReg(IA64::r2) - .addReg(IA64::r0); - } else { - assert(0 && - "sorry, I don't know how to load this sort of reg from the stack\n"); - } -} - -void IA64InstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const { - unsigned Opc = 0; - if (RC == IA64::FPRegisterClass) { - Opc = IA64::LDF8; - } else if (RC == IA64::GRRegisterClass) { - Opc = IA64::LD8; - } else if (RC == IA64::PRRegisterClass) { - Opc = IA64::LD1; - } else { - assert(0 && - "sorry, I don't know how to load this sort of reg\n"); - } - - DebugLoc DL = DebugLoc::getUnknownLoc(); - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); - for (unsigned i = 0, e = Addr.size(); i != e; ++i) - MIB.addOperand(Addr[i]); - NewMIs.push_back(MIB); - return; -} diff --git a/lib/Target/IA64/IA64InstrInfo.h b/lib/Target/IA64/IA64InstrInfo.h deleted file mode 100644 index 79236c2..0000000 --- a/lib/Target/IA64/IA64InstrInfo.h +++ /dev/null @@ -1,70 +0,0 @@ -//===- IA64InstrInfo.h - IA64 Instruction Information ----------*- C++ -*- ===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the IA64 implementation of the TargetInstrInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef IA64INSTRUCTIONINFO_H -#define IA64INSTRUCTIONINFO_H - -#include "llvm/Target/TargetInstrInfo.h" -#include "IA64RegisterInfo.h" - -namespace llvm { - -class IA64InstrInfo : public TargetInstrInfoImpl { - const IA64RegisterInfo RI; -public: - IA64InstrInfo(); - - /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As - /// such, whenever a client has an instance of instruction info, it should - /// always be able to get register info as well (through this method). - /// - virtual const IA64RegisterInfo &getRegisterInfo() const { return RI; } - - /// Return true if the instruction is a register to register move and return - /// the source and dest operands and their sub-register indices by reference. - virtual bool isMoveInstr(const MachineInstr &MI, - unsigned &SrcReg, unsigned &DstReg, - unsigned &SrcSubIdx, unsigned &DstSubIdx) const; - virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl<MachineOperand> &Cond) const; - virtual bool copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *DestRC, - const TargetRegisterClass *SrcRC) const; - virtual void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, int FrameIndex, - const TargetRegisterClass *RC) const; - - virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const; - - virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex, - const TargetRegisterClass *RC) const; - - virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const; -}; - -} // End llvm namespace - -#endif - diff --git a/lib/Target/IA64/IA64InstrInfo.td b/lib/Target/IA64/IA64InstrInfo.td deleted file mode 100644 index 2ab9897..0000000 --- a/lib/Target/IA64/IA64InstrInfo.td +++ /dev/null @@ -1,751 +0,0 @@ -//===- IA64InstrInfo.td - Describe the IA64 Instruction Set -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file describes the IA64 instruction set, defining the instructions, and -// properties of the instructions which are needed for code generation, machine -// code emission, and analysis. -// -//===----------------------------------------------------------------------===// - -include "IA64InstrFormats.td" - -//===----------------------------------------------------------------------===// -// IA-64 specific DAG Nodes. -// - -def IA64getfd : SDNode<"IA64ISD::GETFD", SDTFPToIntOp, []>; - -def retflag : SDNode<"IA64ISD::RET_FLAG", SDTNone, - [SDNPHasChain, SDNPOptInFlag]>; - -//===--------- -// Instruction types - -class isA { bit A=1; } // I or M unit -class isM { bit M=1; } // M unit -class isI { bit I=1; } // I unit -class isB { bit B=1; } // B unit -class isF { bit F=1; } // F unit -class isLX { bit LX=1; } // I/B - -//===--------- - -def u2imm : Operand<i8>; -def u6imm : Operand<i8>; -def s8imm : Operand<i8> { - let PrintMethod = "printS8ImmOperand"; -} -def s14imm : Operand<i64> { - let PrintMethod = "printS14ImmOperand"; -} -def s22imm : Operand<i64> { - let PrintMethod = "printS22ImmOperand"; -} -def u64imm : Operand<i64> { - let PrintMethod = "printU64ImmOperand"; -} -def s64imm : Operand<i64> { - let PrintMethod = "printS64ImmOperand"; -} - -let PrintMethod = "printGlobalOperand" in - def globaladdress : Operand<i64>; - -// the asmprinter needs to know about calls -let PrintMethod = "printCallOperand" in - def calltarget : Operand<i64>; - -/* new daggy action!!! */ - -def is32ones : PatLeaf<(i64 imm), [{ - // is32ones predicate - True if the immediate is 0x00000000FFFFFFFF - // Used to create ZXT4s appropriately - uint64_t v = (uint64_t)N->getZExtValue(); - return (v == 0x00000000FFFFFFFFLL); -}]>; - -// isMIXable predicates - True if the immediate is -// 0xFF00FF00FF00FF00, 0x00FF00FF00FF00FF -// etc, through 0x00000000FFFFFFFF -// Used to test for the suitability of mix* -def isMIX1Lable: PatLeaf<(i64 imm), [{ - return((uint64_t)N->getZExtValue()==0xFF00FF00FF00FF00LL); -}]>; -def isMIX1Rable: PatLeaf<(i64 imm), [{ - return((uint64_t)N->getZExtValue()==0x00FF00FF00FF00FFLL); -}]>; -def isMIX2Lable: PatLeaf<(i64 imm), [{ - return((uint64_t)N->getZExtValue()==0xFFFF0000FFFF0000LL); -}]>; -def isMIX2Rable: PatLeaf<(i64 imm), [{ - return((uint64_t)N->getZExtValue()==0x0000FFFF0000FFFFLL); -}]>; -def isMIX4Lable: PatLeaf<(i64 imm), [{ - return((uint64_t)N->getZExtValue()==0xFFFFFFFF00000000LL); -}]>; -def isMIX4Rable: PatLeaf<(i64 imm), [{ - return((uint64_t)N->getZExtValue()==0x00000000FFFFFFFFLL); -}]>; - -def isSHLADDimm: PatLeaf<(i64 imm), [{ - // isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4 - // - 0 is *not* okay. - // Used to create shladd instructions appropriately - int64_t v = (int64_t)N->getZExtValue(); - return (v >= 1 && v <= 4); -}]>; - -def immSExt14 : PatLeaf<(i64 imm), [{ - // immSExt14 predicate - True if the immediate fits in a 14-bit sign extended - // field. Used by instructions like 'adds'. - int64_t v = (int64_t)N->getZExtValue(); - return (v <= 8191 && v >= -8192); -}]>; - -// imm64 predicate - True if the immediate fits in a 64-bit -// field - i.e., true. used to keep movl happy -def imm64 : PatLeaf<(i64 imm)>; - -def ADD : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "add $dst = $src1, $src2", - [(set GR:$dst, (add GR:$src1, GR:$src2))]>, isA; - -def ADD1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "add $dst = $src1, $src2, 1", - [(set GR:$dst, (add (add GR:$src1, GR:$src2), 1))]>, isA; - -def ADDS : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s14imm:$imm), - "adds $dst = $imm, $src1", - [(set GR:$dst, (add GR:$src1, immSExt14:$imm))]>, isA; - -def MOVL : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins s64imm:$imm), - "movl $dst = $imm", - [(set GR:$dst, imm64:$imm)]>, isLX; - -def ADDL_GA : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, globaladdress:$imm), - "addl $dst = $imm, $src1", - []>, isA; - -// hmm -def ADDL_EA : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, calltarget:$imm), - "addl $dst = $imm, $src1", - []>, isA; - -def SUB : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "sub $dst = $src1, $src2", - [(set GR:$dst, (sub GR:$src1, GR:$src2))]>, isA; - -def SUB1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "sub $dst = $src1, $src2, 1", - [(set GR:$dst, (add (sub GR: $src1, GR:$src2), -1))]>, isA; - -let isTwoAddress = 1 in { -def TPCADDIMM22 : AForm<0x03, 0x0b, - (outs GR:$dst), (ins GR:$src1, s22imm:$imm, PR:$qp), - "($qp) add $dst = $imm, $dst">, isA; -def TPCADDS : AForm_DAG<0x03, 0x0b, - (outs GR:$dst), (ins GR:$src1, s14imm:$imm, PR:$qp), - "($qp) adds $dst = $imm, $dst", - []>, isA; -def TPCMPIMM8NE : AForm<0x03, 0x0b, - (outs PR:$dst), (ins PR:$src1, s22imm:$imm, GR:$src2, PR:$qp), - "($qp) cmp.ne $dst , p0 = $imm, $src2">, isA; -} - -// zero extend a bool (predicate reg) into an integer reg -def ZXTb : Pat<(zext PR:$src), - (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src)>; -def AXTb : Pat<(anyext PR:$src), - (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src)>; - -// normal sign/zero-extends -def SXT1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "sxt1 $dst = $src", - [(set GR:$dst, (sext_inreg GR:$src, i8))]>, isI; -def ZXT1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "zxt1 $dst = $src", - [(set GR:$dst, (and GR:$src, 255))]>, isI; -def SXT2 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "sxt2 $dst = $src", - [(set GR:$dst, (sext_inreg GR:$src, i16))]>, isI; -def ZXT2 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "zxt2 $dst = $src", - [(set GR:$dst, (and GR:$src, 65535))]>, isI; -def SXT4 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "sxt4 $dst = $src", - [(set GR:$dst, (sext_inreg GR:$src, i32))]>, isI; -def ZXT4 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "zxt4 $dst = $src", - [(set GR:$dst, (and GR:$src, is32ones))]>, isI; - -// fixme: shrs vs shru? -def MIX1L : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "mix1.l $dst = $src1, $src2", - [(set GR:$dst, (or (and GR:$src1, isMIX1Lable), - (and (srl GR:$src2, (i64 8)), isMIX1Lable)))]>, isI; - -def MIX2L : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "mix2.l $dst = $src1, $src2", - [(set GR:$dst, (or (and GR:$src1, isMIX2Lable), - (and (srl GR:$src2, (i64 16)), isMIX2Lable)))]>, isI; - -def MIX4L : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "mix4.l $dst = $src1, $src2", - [(set GR:$dst, (or (and GR:$src1, isMIX4Lable), - (and (srl GR:$src2, (i64 32)), isMIX4Lable)))]>, isI; - -def MIX1R : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "mix1.r $dst = $src1, $src2", - [(set GR:$dst, (or (and (shl GR:$src1, (i64 8)), isMIX1Rable), - (and GR:$src2, isMIX1Rable)))]>, isI; - -def MIX2R : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "mix2.r $dst = $src1, $src2", - [(set GR:$dst, (or (and (shl GR:$src1, (i64 16)), isMIX2Rable), - (and GR:$src2, isMIX2Rable)))]>, isI; - -def MIX4R : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "mix4.r $dst = $src1, $src2", - [(set GR:$dst, (or (and (shl GR:$src1, (i64 32)), isMIX4Rable), - (and GR:$src2, isMIX4Rable)))]>, isI; - -def GETFSIGD : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins FP:$src), - "getf.sig $dst = $src", - []>, isM; - -def SETFSIGD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins GR:$src), - "setf.sig $dst = $src", - []>, isM; - -def XMALD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "xma.l $dst = $src1, $src2, $src3", - []>, isF; -def XMAHD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "xma.h $dst = $src1, $src2, $src3", - []>, isF; -def XMAHUD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "xma.hu $dst = $src1, $src2, $src3", - []>, isF; - -// pseudocode for integer multiplication -def : Pat<(mul GR:$src1, GR:$src2), - (GETFSIGD (XMALD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; -def : Pat<(mulhs GR:$src1, GR:$src2), - (GETFSIGD (XMAHD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; -def : Pat<(mulhu GR:$src1, GR:$src2), - (GETFSIGD (XMAHUD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; - -// TODO: addp4 (addp4 dst = src, r0 is a 32-bit add) -// has imm form, too - -// def ADDS : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s14imm:$imm), -// "adds $dst = $imm, $src1">; - -def AND : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "and $dst = $src1, $src2", - [(set GR:$dst, (and GR:$src1, GR:$src2))]>, isA; -def ANDCM : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "andcm $dst = $src1, $src2", - [(set GR:$dst, (and GR:$src1, (not GR:$src2)))]>, isA; -// TODO: and/andcm/or/xor/add/sub/shift immediate forms -def OR : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "or $dst = $src1, $src2", - [(set GR:$dst, (or GR:$src1, GR:$src2))]>, isA; - -def pOR : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2, PR:$qp), - "($qp) or $dst = $src1, $src2">, isA; - -// the following are all a bit unfortunate: we throw away the complement -// of the compare! -def CMPEQ : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.eq $dst, p0 = $src1, $src2", - [(set PR:$dst, (seteq GR:$src1, GR:$src2))]>, isA; -def CMPGT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.gt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setgt GR:$src1, GR:$src2))]>, isA; -def CMPGE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.ge $dst, p0 = $src1, $src2", - [(set PR:$dst, (setge GR:$src1, GR:$src2))]>, isA; -def CMPLT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.lt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setlt GR:$src1, GR:$src2))]>, isA; -def CMPLE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.le $dst, p0 = $src1, $src2", - [(set PR:$dst, (setle GR:$src1, GR:$src2))]>, isA; -def CMPNE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.ne $dst, p0 = $src1, $src2", - [(set PR:$dst, (setne GR:$src1, GR:$src2))]>, isA; -def CMPLTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.ltu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setult GR:$src1, GR:$src2))]>, isA; -def CMPGTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.gtu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setugt GR:$src1, GR:$src2))]>, isA; -def CMPLEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.leu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setule GR:$src1, GR:$src2))]>, isA; -def CMPGEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2), - "cmp.geu $dst, p0 = $src1, $src2", - [(set PR:$dst, (setuge GR:$src1, GR:$src2))]>, isA; - -// and we do the whole thing again for FP compares! -def FCMPEQ : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.eq $dst, p0 = $src1, $src2", - [(set PR:$dst, (seteq FP:$src1, FP:$src2))]>, isF; -def FCMPGT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.gt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setgt FP:$src1, FP:$src2))]>, isF; -def FCMPGE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.ge $dst, p0 = $src1, $src2", - [(set PR:$dst, (setge FP:$src1, FP:$src2))]>, isF; -def FCMPLT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.lt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setlt FP:$src1, FP:$src2))]>, isF; -def FCMPLE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.le $dst, p0 = $src1, $src2", - [(set PR:$dst, (setle FP:$src1, FP:$src2))]>, isF; -def FCMPNE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.neq $dst, p0 = $src1, $src2", - [(set PR:$dst, (setne FP:$src1, FP:$src2))]>, isF; -def FCMPLTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.lt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setult FP:$src1, FP:$src2))]>, isF; -def FCMPGTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.gt $dst, p0 = $src1, $src2", - [(set PR:$dst, (setugt FP:$src1, FP:$src2))]>, isF; -def FCMPLEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.le $dst, p0 = $src1, $src2", - [(set PR:$dst, (setule FP:$src1, FP:$src2))]>, isF; -def FCMPGEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2), - "fcmp.ge $dst, p0 = $src1, $src2", - [(set PR:$dst, (setuge FP:$src1, FP:$src2))]>, isF; - -def PCMPEQUNCR0R0 : AForm<0x03, 0x0b, (outs PR:$dst), (ins PR:$qp), - "($qp) cmp.eq.unc $dst, p0 = r0, r0">, isA; - -def : Pat<(trunc GR:$src), // truncate i64 to i1 - (CMPNE GR:$src, r0)>; // $src!=0? If so, PR:$dst=true - -let isTwoAddress=1 in { - def TPCMPEQR0R0 : AForm<0x03, 0x0b, (outs PR:$dst), (ins PR:$bogus, PR:$qp), - "($qp) cmp.eq $dst, p0 = r0, r0">, isA; - def TPCMPNER0R0 : AForm<0x03, 0x0b, (outs PR:$dst), (ins PR:$bogus, PR:$qp), - "($qp) cmp.ne $dst, p0 = r0, r0">, isA; -} - -/* our pseudocode for OR on predicates is: -pC = pA OR pB -------------- -(pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA - ;; -(pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1 */ - -def bOR : Pat<(or PR:$src1, PR:$src2), - (TPCMPEQR0R0 (PCMPEQUNCR0R0 PR:$src1), PR:$src2)>; - -/* our pseudocode for AND on predicates is: - * -(pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA - cmp.eq pTemp,p0 = r0,r0 // pTemp = NOT pB - ;; -(pB) cmp.ne pTemp,p0 = r0,r0 - ;; -(pTemp)cmp.ne pC,p0 = r0,r0 // if (NOT pB) pC = 0 */ - -def bAND : Pat<(and PR:$src1, PR:$src2), - ( TPCMPNER0R0 (PCMPEQUNCR0R0 PR:$src1), - (TPCMPNER0R0 (CMPEQ r0, r0), PR:$src2) )>; - -/* one possible routine for XOR on predicates is: - - // Compute px = py ^ pz - // using sum of products: px = (py & !pz) | (pz & !py) - // Uses 5 instructions in 3 cycles. - // cycle 1 -(pz) cmp.eq.unc px = r0, r0 // px = pz -(py) cmp.eq.unc pt = r0, r0 // pt = py - ;; - // cycle 2 -(pt) cmp.ne.and px = r0, r0 // px = px & !pt (px = pz & !pt) -(pz) cmp.ne.and pt = r0, r0 // pt = pt & !pz - ;; - } { .mmi - // cycle 3 -(pt) cmp.eq.or px = r0, r0 // px = px | pt - -*** Another, which we use here, requires one scratch GR. it is: - - mov rt = 0 // initialize rt off critical path - ;; - - // cycle 1 -(pz) cmp.eq.unc px = r0, r0 // px = pz -(pz) mov rt = 1 // rt = pz - ;; - // cycle 2 -(py) cmp.ne px = 1, rt // if (py) px = !pz - -.. these routines kindly provided by Jim Hull -*/ - -def bXOR : Pat<(xor PR:$src1, PR:$src2), - (TPCMPIMM8NE (PCMPEQUNCR0R0 PR:$src2), 1, - (TPCADDS (ADDS r0, 0), 1, PR:$src2), - PR:$src1)>; - -def XOR : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "xor $dst = $src1, $src2", - [(set GR:$dst, (xor GR:$src1, GR:$src2))]>, isA; - -def SHLADD: AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1,s64imm:$imm,GR:$src2), - "shladd $dst = $src1, $imm, $src2", - [(set GR:$dst, (add GR:$src2, (shl GR:$src1, isSHLADDimm:$imm)))]>, isA; - -def SHL : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "shl $dst = $src1, $src2", - [(set GR:$dst, (shl GR:$src1, GR:$src2))]>, isI; - -def SHRU : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "shr.u $dst = $src1, $src2", - [(set GR:$dst, (srl GR:$src1, GR:$src2))]>, isI; - -def SHRS : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2), - "shr $dst = $src1, $src2", - [(set GR:$dst, (sra GR:$src1, GR:$src2))]>, isI; - -def MOV : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "mov $dst = $src">, isA; -def FMOV : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "mov $dst = $src">, isF; // XXX: there _is_ no fmov -def PMOV : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src, PR:$qp), - "($qp) mov $dst = $src">, isA; - -def SPILL_ALL_PREDICATES_TO_GR : AForm<0x03, 0x0b, (outs GR:$dst), (ins), - "mov $dst = pr">, isI; -def FILL_ALL_PREDICATES_FROM_GR : AForm<0x03, 0x0b, (outs), (ins GR:$src), - "mov pr = $src">, isI; - -let isTwoAddress = 1 in { - def CMOV : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src2, GR:$src, PR:$qp), - "($qp) mov $dst = $src">, isA; -} - -def PFMOV : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src, PR:$qp), - "($qp) mov $dst = $src">, isF; - -let isTwoAddress = 1 in { - def CFMOV : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src2, FP:$src, PR:$qp), - "($qp) mov $dst = $src">, isF; -} - -def SELECTINT : Pat<(select PR:$which, GR:$src1, GR:$src2), - (CMOV (MOV GR:$src2), GR:$src1, PR:$which)>; // note order! -def SELECTFP : Pat<(select PR:$which, FP:$src1, FP:$src2), - (CFMOV (FMOV FP:$src2), FP:$src1, PR:$which)>; // note order! -// TODO: can do this faster, w/o using any integer regs (see pattern isel) -def SELECTBOOL : Pat<(select PR:$which, PR:$src1, PR:$src2), // note order! - (CMPNE (CMOV - (MOV (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src2)), - (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src1), PR:$which), r0)>; - -// load constants of various sizes // FIXME: prettyprint -ve constants -def : Pat<(i64 immSExt14:$imm), (ADDS r0, immSExt14:$imm)>; -def : Pat<(i1 -1), (CMPEQ r0, r0)>; // TODO: this should just be a ref to p0 -def : Pat<(i1 0), (CMPNE r0, r0)>; // TODO: any instruction actually *using* - // this predicate should be killed! - -// TODO: support postincrement (reg, imm9) loads+stores - this needs more -// tablegen support - -def IUSE : PseudoInstIA64<(outs), (ins variable_ops), "// IUSE">; -def ADJUSTCALLSTACKUP : PseudoInstIA64<(outs), (ins variable_ops), - "// ADJUSTCALLSTACKUP">; -def ADJUSTCALLSTACKDOWN : PseudoInstIA64<(outs), (ins variable_ops), - "// ADJUSTCALLSTACKDOWN">; -def PSEUDO_ALLOC : PseudoInstIA64<(outs), (ins GR:$foo), "// PSEUDO_ALLOC">; - -def ALLOC : AForm<0x03, 0x0b, - (outs GR:$dst), (ins i8imm:$inputs, i8imm:$locals, i8imm:$outputs, i8imm:$rotating), - "alloc $dst = ar.pfs,$inputs,$locals,$outputs,$rotating">, isM; - -let isTwoAddress = 1 in { - def TCMPNE : AForm<0x03, 0x0b, - (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4), - "cmp.ne $dst, p0 = $src3, $src4">, isA; - - def TPCMPEQOR : AForm<0x03, 0x0b, - (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4, PR:$qp), - "($qp) cmp.eq.or $dst, p0 = $src3, $src4">, isA; - - def TPCMPNE : AForm<0x03, 0x0b, - (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4, PR:$qp), - "($qp) cmp.ne $dst, p0 = $src3, $src4">, isA; - - def TPCMPEQ : AForm<0x03, 0x0b, - (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4, PR:$qp), - "($qp) cmp.eq $dst, p0 = $src3, $src4">, isA; -} - -def MOVSIMM14 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s14imm:$imm), - "mov $dst = $imm">, isA; -def MOVSIMM22 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s22imm:$imm), - "mov $dst = $imm">, isA; -def MOVLIMM64 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s64imm:$imm), - "movl $dst = $imm">, isLX; - -def SHLI : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, u6imm:$imm), - "shl $dst = $src1, $imm">, isI; -def SHRUI : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, u6imm:$imm), - "shr.u $dst = $src1, $imm">, isI; -def SHRSI : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, u6imm:$imm), - "shr $dst = $src1, $imm">, isI; - -def EXTRU : AForm<0x03, 0x0b, - (outs GR:$dst), (ins GR:$src1, u6imm:$imm1, u6imm:$imm2), - "extr.u $dst = $src1, $imm1, $imm2">, isI; - -def DEPZ : AForm<0x03, 0x0b, - (outs GR:$dst), (ins GR:$src1, u6imm:$imm1, u6imm:$imm2), - "dep.z $dst = $src1, $imm1, $imm2">, isI; - -def PCMPEQOR : AForm<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2, PR:$qp), - "($qp) cmp.eq.or $dst, p0 = $src1, $src2">, isA; -def PCMPEQUNC : AForm<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2, PR:$qp), - "($qp) cmp.eq.unc $dst, p0 = $src1, $src2">, isA; -def PCMPNE : AForm<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2, PR:$qp), - "($qp) cmp.ne $dst, p0 = $src1, $src2">, isA; - -// two destinations! -def BCMPEQ : AForm<0x03, 0x0b, (outs PR:$dst1, PR:$dst2), (ins GR:$src1, GR:$src2), - "cmp.eq $dst1, dst2 = $src1, $src2">, isA; - -def ADDIMM14 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s14imm:$imm), - "adds $dst = $imm, $src1">, isA; - -def ADDIMM22 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s22imm:$imm), - "add $dst = $imm, $src1">, isA; -def CADDIMM22 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s22imm:$imm, PR:$qp), - "($qp) add $dst = $imm, $src1">, isA; - -def SUBIMM8 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s8imm:$imm, GR:$src2), - "sub $dst = $imm, $src2">, isA; - -let mayStore = 1 in { - def ST1 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value), - "st1 [$dstPtr] = $value">, isM; - def ST2 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value), - "st2 [$dstPtr] = $value">, isM; - def ST4 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value), - "st4 [$dstPtr] = $value">, isM; - def ST8 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value), - "st8 [$dstPtr] = $value">, isM; - def STF4 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, FP:$value), - "stfs [$dstPtr] = $value">, isM; - def STF8 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, FP:$value), - "stfd [$dstPtr] = $value">, isM; - def STF_SPILL : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, FP:$value), - "stf.spill [$dstPtr] = $value">, isM; -} - -let canFoldAsLoad = 1 in { - def LD1 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr), - "ld1 $dst = [$srcPtr]">, isM; - def LD2 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr), - "ld2 $dst = [$srcPtr]">, isM; - def LD4 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr), - "ld4 $dst = [$srcPtr]">, isM; - def LD8 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr), - "ld8 $dst = [$srcPtr]">, isM; - def LDF4 : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$srcPtr), - "ldfs $dst = [$srcPtr]">, isM; - def LDF8 : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$srcPtr), - "ldfd $dst = [$srcPtr]">, isM; - def LDF_FILL : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$srcPtr), - "ldf.fill $dst = [$srcPtr]">, isM; -} - -def POPCNT : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), - "popcnt $dst = $src", - [(set GR:$dst, (ctpop GR:$src))]>, isI; - -// some FP stuff: // TODO: single-precision stuff? -def FADD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2), - "fadd $dst = $src1, $src2", - [(set FP:$dst, (fadd FP:$src1, FP:$src2))]>, isF; -def FADDS: AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2), - "fadd.s $dst = $src1, $src2">, isF; -def FSUB : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2), - "fsub $dst = $src1, $src2", - [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>, isF; -def FMPY : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2), - "fmpy $dst = $src1, $src2", - [(set FP:$dst, (fmul FP:$src1, FP:$src2))]>, isF; -def FMA : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "fma $dst = $src1, $src2, $src3", - [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>, isF; -def FMS : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "fms $dst = $src1, $src2, $src3", - [(set FP:$dst, (fsub (fmul FP:$src1, FP:$src2), FP:$src3))]>, isF; -def FNMA : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "fnma $dst = $src1, $src2, $src3", - [(set FP:$dst, (fneg (fadd (fmul FP:$src1, FP:$src2), FP:$src3)))]>, isF; -def FABS : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fabs $dst = $src", - [(set FP:$dst, (fabs FP:$src))]>, isF; -def FNEG : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fneg $dst = $src", - [(set FP:$dst, (fneg FP:$src))]>, isF; -def FNEGABS : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fnegabs $dst = $src", - [(set FP:$dst, (fneg (fabs FP:$src)))]>, isF; - -let isTwoAddress=1 in { -def TCFMAS1 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$bogussrc, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.s1 $dst = $src1, $src2, $src3">, isF; -def TCFMADS0 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$bogussrc, FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.d.s0 $dst = $src1, $src2, $src3">, isF; -} - -def CFMAS1 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.s1 $dst = $src1, $src2, $src3">, isF; -def CFNMAS1 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fnma.s1 $dst = $src1, $src2, $src3">, isF; - -def CFMADS1 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.d.s1 $dst = $src1, $src2, $src3">, isF; -def CFMADS0 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fma.d.s0 $dst = $src1, $src2, $src3">, isF; -def CFNMADS1 : AForm<0x03, 0x0b, - (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp), - "($qp) fnma.d.s1 $dst = $src1, $src2, $src3">, isF; - -def FRCPAS0 : AForm<0x03, 0x0b, (outs FP:$dstFR, PR:$dstPR), (ins FP:$src1, FP:$src2), - "frcpa.s0 $dstFR, $dstPR = $src1, $src2">, isF; -def FRCPAS1 : AForm<0x03, 0x0b, (outs FP:$dstFR, PR:$dstPR), (ins FP:$src1, FP:$src2), - "frcpa.s1 $dstFR, $dstPR = $src1, $src2">, isF; - -def XMAL : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3), - "xma.l $dst = $src1, $src2, $src3">, isF; - -def FCVTXF : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.xf $dst = $src">, isF; -def FCVTXUF : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.xuf $dst = $src">, isF; -def FCVTXUFS1 : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.xuf.s1 $dst = $src">, isF; -def FCVTFX : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.fx $dst = $src">, isF; -def FCVTFXU : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.fxu $dst = $src">, isF; - -def FCVTFXTRUNC : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.fx.trunc $dst = $src">, isF; -def FCVTFXUTRUNC : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.fxu.trunc $dst = $src">, isF; - -def FCVTFXTRUNCS1 : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.fx.trunc.s1 $dst = $src">, isF; -def FCVTFXUTRUNCS1 : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fcvt.fxu.trunc.s1 $dst = $src">, isF; - -def FNORMD : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src), - "fnorm.d $dst = $src">, isF; - -def GETFD : AForm<0x03, 0x0b, (outs GR:$dst), (ins FP:$src), - "getf.d $dst = $src">, isM; -def SETFD : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$src), - "setf.d $dst = $src">, isM; - -def GETFSIG : AForm<0x03, 0x0b, (outs GR:$dst), (ins FP:$src), - "getf.sig $dst = $src">, isM; -def SETFSIG : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$src), - "setf.sig $dst = $src">, isM; - -// these four FP<->int conversion patterns need checking/cleaning -def SINT_TO_FP : Pat<(sint_to_fp GR:$src), - (FNORMD (FCVTXF (SETFSIG GR:$src)))>; -def UINT_TO_FP : Pat<(uint_to_fp GR:$src), - (FNORMD (FCVTXUF (SETFSIG GR:$src)))>; -def FP_TO_SINT : Pat<(i64 (fp_to_sint FP:$src)), - (GETFSIG (FCVTFXTRUNC FP:$src))>; -def FP_TO_UINT : Pat<(i64 (fp_to_uint FP:$src)), - (GETFSIG (FCVTFXUTRUNC FP:$src))>; - -def fpimm0 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(+0.0); -}]>; -def fpimm1 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(+1.0); -}]>; -def fpimmn0 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(-0.0); -}]>; -def fpimmn1 : PatLeaf<(fpimm), [{ - return N->isExactlyValue(-1.0); -}]>; - -def : Pat<(f64 fpimm0), (FMOV F0)>; -def : Pat<(f64 fpimm1), (FMOV F1)>; -def : Pat<(f64 fpimmn0), (FNEG F0)>; -def : Pat<(f64 fpimmn1), (FNEG F1)>; - -let isTerminator = 1, isBranch = 1 in { - def BRL_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins i64imm:$dst), - "(p0) brl.cond.sptk $dst">, isB; - def BRLCOND_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, i64imm:$dst), - "($qp) brl.cond.sptk $dst">, isB; - def BRCOND_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, GR:$dst), - "($qp) br.cond.sptk $dst">, isB; -} - -let isCall = 1, /* isTerminator = 1, isBranch = 1, */ - Uses = [out0,out1,out2,out3,out4,out5,out6,out7], -// all calls clobber non-callee-saved registers, and for now, they are these: - Defs = [r2,r3,r8,r9,r10,r11,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24, - r25,r26,r27,r28,r29,r30,r31, - p6,p7,p8,p9,p10,p11,p12,p13,p14,p15, - F6,F7,F8,F9,F10,F11,F12,F13,F14,F15, - F32,F33,F34,F35,F36,F37,F38,F39,F40,F41,F42,F43,F44,F45,F46,F47,F48,F49, - F50,F51,F52,F53,F54,F55,F56, - F57,F58,F59,F60,F61,F62,F63,F64,F65,F66,F67,F68,F69,F70,F71,F72,F73,F74, - F75,F76,F77,F78,F79,F80,F81, - F82,F83,F84,F85,F86,F87,F88,F89,F90,F91,F92,F93,F94,F95,F96,F97,F98,F99, - F100,F101,F102,F103,F104,F105, - F106,F107,F108,F109,F110,F111,F112,F113,F114,F115,F116,F117,F118,F119, - F120,F121,F122,F123,F124,F125,F126,F127, - out0,out1,out2,out3,out4,out5,out6,out7] in { -// old pattern call - def BRCALL: RawForm<0x03, 0xb0, (outs), (ins calltarget:$dst), - "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs? -// new daggy stuff! - -// calls a globaladdress - def BRCALL_IPREL_GA : RawForm<0x03, 0xb0, (outs), (ins calltarget:$dst), - "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs? -// calls an externalsymbol - def BRCALL_IPREL_ES : RawForm<0x03, 0xb0, (outs), (ins calltarget:$dst), - "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs? -// calls through a function descriptor - def BRCALL_INDIRECT : RawForm<0x03, 0xb0, (outs), (ins GR:$branchreg), - "br.call.sptk rp = $branchreg">, isB; // FIXME: teach llvm about branch regs? - def BRLCOND_CALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, i64imm:$dst), - "($qp) brl.cond.call.sptk $dst">, isB; - def BRCOND_CALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, GR:$dst), - "($qp) br.cond.call.sptk $dst">, isB; -} - -// Return branch: -let isTerminator = 1, isReturn = 1 in - def RET : AForm_DAG<0x03, 0x0b, (outs), (ins), - "br.ret.sptk.many rp", - [(retflag)]>, isB; // return -def : Pat<(ret), (RET)>; - -// the evil stop bit of despair -def STOP : PseudoInstIA64<(outs), (ins variable_ops), ";;">; - diff --git a/lib/Target/IA64/IA64MachineFunctionInfo.h b/lib/Target/IA64/IA64MachineFunctionInfo.h deleted file mode 100644 index e6254d6..0000000 --- a/lib/Target/IA64/IA64MachineFunctionInfo.h +++ /dev/null @@ -1,34 +0,0 @@ -//===-- IA64MachineFunctionInfo.h - IA64-specific information ---*- C++ -*-===// -//===-- for MachineFunction ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -//===----------------------------------------------------------------------===// -// -// This file declares IA64-specific per-machine-function information. -// -//===----------------------------------------------------------------------===// - -#ifndef IA64MACHINEFUNCTIONINFO_H -#define IA64MACHINEFUNCTIONINFO_H - -#include "llvm/CodeGen/MachineFunction.h" -//#include "IA64JITInfo.h" - -namespace llvm { - -class IA64FunctionInfo : public MachineFunctionInfo { - -public: - unsigned outRegsUsed; // how many 'out' registers are used - // by this machinefunction? (used to compute the appropriate - // entry in the 'alloc' instruction at the top of the - // machinefunction) - explicit IA64FunctionInfo(MachineFunction& MF) { outRegsUsed=0; }; - -}; - -} // End llvm namespace - -#endif - diff --git a/lib/Target/IA64/IA64RegisterInfo.cpp b/lib/Target/IA64/IA64RegisterInfo.cpp deleted file mode 100644 index 7ad6f51..0000000 --- a/lib/Target/IA64/IA64RegisterInfo.cpp +++ /dev/null @@ -1,319 +0,0 @@ -//===- IA64RegisterInfo.cpp - IA64 Register Information ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the IA64 implementation of the TargetRegisterInfo class. -// This file is responsible for the frame pointer elimination optimization -// on IA64. -// -//===----------------------------------------------------------------------===// - -#include "IA64.h" -#include "IA64RegisterInfo.h" -#include "IA64InstrBuilder.h" -#include "IA64MachineFunctionInfo.h" -#include "llvm/Constants.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineLocation.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" -using namespace llvm; - -IA64RegisterInfo::IA64RegisterInfo(const TargetInstrInfo &tii) - : IA64GenRegisterInfo(IA64::ADJUSTCALLSTACKDOWN, IA64::ADJUSTCALLSTACKUP), - TII(tii) {} - -const unsigned* IA64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) - const { - static const unsigned CalleeSavedRegs[] = { - IA64::r5, 0 - }; - return CalleeSavedRegs; -} - -const TargetRegisterClass* const* -IA64RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { - static const TargetRegisterClass * const CalleeSavedRegClasses[] = { - &IA64::GRRegClass, 0 - }; - return CalleeSavedRegClasses; -} - -BitVector IA64RegisterInfo::getReservedRegs(const MachineFunction &MF) const { - BitVector Reserved(getNumRegs()); - Reserved.set(IA64::r0); - Reserved.set(IA64::r1); - Reserved.set(IA64::r2); - Reserved.set(IA64::r5); - Reserved.set(IA64::r12); - Reserved.set(IA64::r13); - Reserved.set(IA64::r22); - Reserved.set(IA64::rp); - return Reserved; -} - -//===----------------------------------------------------------------------===// -// Stack Frame Processing methods -//===----------------------------------------------------------------------===// - -// hasFP - Return true if the specified function should have a dedicated frame -// pointer register. This is true if the function has variable sized allocas or -// if frame pointer elimination is disabled. -// -bool IA64RegisterInfo::hasFP(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); -} - -void IA64RegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - if (hasFP(MF)) { - // If we have a frame pointer, turn the adjcallstackup instruction into a - // 'sub SP, <amt>' and the adjcallstackdown instruction into 'add SP, - // <amt>' - MachineInstr *Old = I; - unsigned Amount = Old->getOperand(0).getImm(); - DebugLoc dl = Old->getDebugLoc(); - if (Amount != 0) { - // We need to keep the stack aligned properly. To do this, we round the - // amount of space needed for the outgoing arguments up to the next - // alignment boundary. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - Amount = (Amount+Align-1)/Align*Align; - - // Replace the pseudo instruction with a new instruction... - if (Old->getOpcode() == IA64::ADJUSTCALLSTACKDOWN) { - BuildMI(MBB, I, dl, TII.get(IA64::ADDIMM22), IA64::r12) - .addReg(IA64::r12).addImm(-Amount); - } else { - assert(Old->getOpcode() == IA64::ADJUSTCALLSTACKUP); - BuildMI(MBB, I, dl, TII.get(IA64::ADDIMM22), IA64::r12) - .addReg(IA64::r12).addImm(Amount); - } - } - } - - MBB.erase(I); -} - -void IA64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS)const{ - assert(SPAdj == 0 && "Unexpected"); - - unsigned i = 0; - MachineInstr &MI = *II; - MachineBasicBlock &MBB = *MI.getParent(); - MachineFunction &MF = *MBB.getParent(); - DebugLoc dl = MI.getDebugLoc(); - - bool FP = hasFP(MF); - - while (!MI.getOperand(i).isFI()) { - ++i; - assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); - } - - int FrameIndex = MI.getOperand(i).getIndex(); - - // choose a base register: ( hasFP? framepointer : stack pointer ) - unsigned BaseRegister = FP ? IA64::r5 : IA64::r12; - // Add the base register - MI.getOperand(i).ChangeToRegister(BaseRegister, false); - - // Now add the frame object offset to the offset from r1. - int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); - - // If we're not using a Frame Pointer that has been set to the value of the - // SP before having the stack size subtracted from it, then add the stack size - // to Offset to get the correct offset. - Offset += MF.getFrameInfo()->getStackSize(); - - // XXX: we use 'r22' as another hack+slash temporary register here :( - if (Offset <= 8191 && Offset >= -8192) { // smallish offset - // Fix up the old: - MI.getOperand(i).ChangeToRegister(IA64::r22, false); - //insert the new - BuildMI(MBB, II, dl, TII.get(IA64::ADDIMM22), IA64::r22) - .addReg(BaseRegister).addImm(Offset); - } else { // it's big - //fix up the old: - MI.getOperand(i).ChangeToRegister(IA64::r22, false); - BuildMI(MBB, II, dl, TII.get(IA64::MOVLIMM64), IA64::r22).addImm(Offset); - BuildMI(MBB, II, dl, TII.get(IA64::ADD), IA64::r22).addReg(BaseRegister) - .addReg(IA64::r22); - } - -} - -void IA64RegisterInfo::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB - MachineBasicBlock::iterator MBBI = MBB.begin(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - bool FP = hasFP(MF); - DebugLoc dl = (MBBI != MBB.end() ? - MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); - - // first, we handle the 'alloc' instruction, that should be right up the - // top of any function - static const unsigned RegsInOrder[96] = { // there are 96 GPRs the - // RSE worries about - IA64::r32, IA64::r33, IA64::r34, IA64::r35, - IA64::r36, IA64::r37, IA64::r38, IA64::r39, IA64::r40, IA64::r41, - IA64::r42, IA64::r43, IA64::r44, IA64::r45, IA64::r46, IA64::r47, - IA64::r48, IA64::r49, IA64::r50, IA64::r51, IA64::r52, IA64::r53, - IA64::r54, IA64::r55, IA64::r56, IA64::r57, IA64::r58, IA64::r59, - IA64::r60, IA64::r61, IA64::r62, IA64::r63, IA64::r64, IA64::r65, - IA64::r66, IA64::r67, IA64::r68, IA64::r69, IA64::r70, IA64::r71, - IA64::r72, IA64::r73, IA64::r74, IA64::r75, IA64::r76, IA64::r77, - IA64::r78, IA64::r79, IA64::r80, IA64::r81, IA64::r82, IA64::r83, - IA64::r84, IA64::r85, IA64::r86, IA64::r87, IA64::r88, IA64::r89, - IA64::r90, IA64::r91, IA64::r92, IA64::r93, IA64::r94, IA64::r95, - IA64::r96, IA64::r97, IA64::r98, IA64::r99, IA64::r100, IA64::r101, - IA64::r102, IA64::r103, IA64::r104, IA64::r105, IA64::r106, IA64::r107, - IA64::r108, IA64::r109, IA64::r110, IA64::r111, IA64::r112, IA64::r113, - IA64::r114, IA64::r115, IA64::r116, IA64::r117, IA64::r118, IA64::r119, - IA64::r120, IA64::r121, IA64::r122, IA64::r123, IA64::r124, IA64::r125, - IA64::r126, IA64::r127 }; - - unsigned numStackedGPRsUsed=0; - for (int i=0; i != 96; i++) { - if (MF.getRegInfo().isPhysRegUsed(RegsInOrder[i])) - numStackedGPRsUsed=i+1; // (i+1 and not ++ - consider fn(fp, fp, int) - } - - unsigned numOutRegsUsed=MF.getInfo<IA64FunctionInfo>()->outRegsUsed; - - // XXX FIXME : this code should be a bit more reliable (in case there _isn't_ - // a pseudo_alloc in the MBB) - unsigned dstRegOfPseudoAlloc; - for(MBBI = MBB.begin(); /*MBBI->getOpcode() != IA64::PSEUDO_ALLOC*/; ++MBBI) { - assert(MBBI != MBB.end()); - if(MBBI->getOpcode() == IA64::PSEUDO_ALLOC) { - dstRegOfPseudoAlloc=MBBI->getOperand(0).getReg(); - break; - } - } - - if (MBBI != MBB.end()) dl = MBBI->getDebugLoc(); - - BuildMI(MBB, MBBI, dl, TII.get(IA64::ALLOC)). - addReg(dstRegOfPseudoAlloc).addImm(0). - addImm(numStackedGPRsUsed).addImm(numOutRegsUsed).addImm(0); - - // Get the number of bytes to allocate from the FrameInfo - unsigned NumBytes = MFI->getStackSize(); - - if(FP) - NumBytes += 8; // reserve space for the old FP - - // Do we need to allocate space on the stack? - if (NumBytes == 0) - return; - - // Add 16 bytes at the bottom of the stack (scratch area) - // and round the size to a multiple of the alignment. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - unsigned Size = 16 + (FP ? 8 : 0); - NumBytes = (NumBytes+Size+Align-1)/Align*Align; - - // Update frame info to pretend that this is part of the stack... - MFI->setStackSize(NumBytes); - - // adjust stack pointer: r12 -= numbytes - if (NumBytes <= 8191) { - BuildMI(MBB, MBBI, dl, TII.get(IA64::ADDIMM22),IA64::r12).addReg(IA64::r12). - addImm(-NumBytes); - } else { // we use r22 as a scratch register here - // first load the decrement into r22 - BuildMI(MBB, MBBI, dl, TII.get(IA64::MOVLIMM64), IA64::r22). - addImm(-NumBytes); - // FIXME: MOVLSI32 expects a _u_32imm - // then add (subtract) it to r12 (stack ptr) - BuildMI(MBB, MBBI, dl, TII.get(IA64::ADD), IA64::r12) - .addReg(IA64::r12).addReg(IA64::r22); - - } - - // now if we need to, save the old FP and set the new - if (FP) { - BuildMI(MBB, MBBI,dl,TII.get(IA64::ST8)).addReg(IA64::r12).addReg(IA64::r5); - // this must be the last instr in the prolog ? (XXX: why??) - BuildMI(MBB, MBBI, dl, TII.get(IA64::MOV), IA64::r5).addReg(IA64::r12); - } - -} - -void IA64RegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock::iterator MBBI = prior(MBB.end()); - assert(MBBI->getOpcode() == IA64::RET && - "Can only insert epilog into returning blocks"); - DebugLoc dl = MBBI->getDebugLoc(); - bool FP = hasFP(MF); - - // Get the number of bytes allocated from the FrameInfo... - unsigned NumBytes = MFI->getStackSize(); - - //now if we need to, restore the old FP - if (FP) { - //copy the FP into the SP (discards allocas) - BuildMI(MBB, MBBI, dl, TII.get(IA64::MOV), IA64::r12).addReg(IA64::r5); - //restore the FP - BuildMI(MBB, MBBI, dl, TII.get(IA64::LD8), IA64::r5).addReg(IA64::r5); - } - - if (NumBytes != 0) { - if (NumBytes <= 8191) { - BuildMI(MBB, MBBI, dl, TII.get(IA64::ADDIMM22),IA64::r12). - addReg(IA64::r12).addImm(NumBytes); - } else { - BuildMI(MBB, MBBI, dl, TII.get(IA64::MOVLIMM64), IA64::r22). - addImm(NumBytes); - BuildMI(MBB, MBBI, dl, TII.get(IA64::ADD), IA64::r12).addReg(IA64::r12). - addReg(IA64::r22); - } - } -} - -unsigned IA64RegisterInfo::getRARegister() const { - assert(0 && "What is the return address register"); - return 0; -} - -unsigned IA64RegisterInfo::getFrameRegister(MachineFunction &MF) const { - return hasFP(MF) ? IA64::r5 : IA64::r12; -} - -unsigned IA64RegisterInfo::getEHExceptionRegister() const { - assert(0 && "What is the exception register"); - return 0; -} - -unsigned IA64RegisterInfo::getEHHandlerRegister() const { - assert(0 && "What is the exception handler register"); - return 0; -} - -int IA64RegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { - assert(0 && "What is the dwarf register number"); - return -1; -} - -#include "IA64GenRegisterInfo.inc" - diff --git a/lib/Target/IA64/IA64RegisterInfo.h b/lib/Target/IA64/IA64RegisterInfo.h deleted file mode 100644 index 0c5083e..0000000 --- a/lib/Target/IA64/IA64RegisterInfo.h +++ /dev/null @@ -1,63 +0,0 @@ -//===- IA64RegisterInfo.h - IA64 Register Information Impl ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the IA64 implementation of the TargetRegisterInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef IA64REGISTERINFO_H -#define IA64REGISTERINFO_H - -#include "llvm/Target/TargetRegisterInfo.h" -#include "IA64GenRegisterInfo.h.inc" - -namespace llvm { - -class TargetInstrInfo; - -struct IA64RegisterInfo : public IA64GenRegisterInfo { - const TargetInstrInfo &TII; - - IA64RegisterInfo(const TargetInstrInfo &tii); - - /// Code Generation virtual methods... - const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const; - - const TargetRegisterClass* const* getCalleeSavedRegClasses( - const MachineFunction *MF = 0) const; - - BitVector getReservedRegs(const MachineFunction &MF) const; - - bool hasFP(const MachineFunction &MF) const; - - void eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI) const; - - void eliminateFrameIndex(MachineBasicBlock::iterator MI, - int SPAdj, RegScavenger *RS = NULL) const; - - void emitPrologue(MachineFunction &MF) const; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; - - // Debug information queries. - unsigned getRARegister() const; - unsigned getFrameRegister(MachineFunction &MF) const; - - // Exception handling queries. - unsigned getEHExceptionRegister() const; - unsigned getEHHandlerRegister() const; - - int getDwarfRegNum(unsigned RegNum, bool isEH) const; -}; - -} // End llvm namespace - -#endif - diff --git a/lib/Target/IA64/IA64RegisterInfo.td b/lib/Target/IA64/IA64RegisterInfo.td deleted file mode 100644 index dd72dc3..0000000 --- a/lib/Target/IA64/IA64RegisterInfo.td +++ /dev/null @@ -1,509 +0,0 @@ -//===- IA64RegisterInfo.td - Describe the IA64 Register File ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file describes the IA64 register file, defining the registers -// themselves, aliases between the registers, and the register classes built -// out of the registers. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Register definitions... -// - -class IA64Register<string n> : Register<n> { - let Namespace = "IA64"; -} - -// GR - One of 128 32-bit general registers -class GR<bits<7> num, string n> : IA64Register<n> { - field bits<7> Num = num; -} - -// FP - One of 128 82-bit floating-point registers -class FP<bits<7> num, string n> : IA64Register<n> { - field bits<7> Num = num; -} - -// PR - One of 64 1-bit predicate registers -class PR<bits<6> num, string n> : IA64Register<n> { - field bits<6> Num = num; -} - -/* general registers */ -def r0 : GR< 0, "r0">, DwarfRegNum<[0]>; -def r1 : GR< 1, "r1">, DwarfRegNum<[1]>; -def r2 : GR< 2, "r2">, DwarfRegNum<[2]>; -def r3 : GR< 3, "r3">, DwarfRegNum<[3]>; -def r4 : GR< 4, "r4">, DwarfRegNum<[4]>; -def r5 : GR< 5, "r5">, DwarfRegNum<[5]>; -def r6 : GR< 6, "r6">, DwarfRegNum<[6]>; -def r7 : GR< 7, "r7">, DwarfRegNum<[7]>; -def r8 : GR< 8, "r8">, DwarfRegNum<[8]>; -def r9 : GR< 9, "r9">, DwarfRegNum<[9]>; -def r10 : GR< 10, "r10">, DwarfRegNum<[10]>; -def r11 : GR< 11, "r11">, DwarfRegNum<[11]>; -def r12 : GR< 12, "r12">, DwarfRegNum<[12]>; -def r13 : GR< 13, "r13">, DwarfRegNum<[13]>; -def r14 : GR< 14, "r14">, DwarfRegNum<[14]>; -def r15 : GR< 15, "r15">, DwarfRegNum<[15]>; -def r16 : GR< 16, "r16">, DwarfRegNum<[16]>; -def r17 : GR< 17, "r17">, DwarfRegNum<[17]>; -def r18 : GR< 18, "r18">, DwarfRegNum<[18]>; -def r19 : GR< 19, "r19">, DwarfRegNum<[19]>; -def r20 : GR< 20, "r20">, DwarfRegNum<[20]>; -def r21 : GR< 21, "r21">, DwarfRegNum<[21]>; -def r22 : GR< 22, "r22">, DwarfRegNum<[22]>; -def r23 : GR< 23, "r23">, DwarfRegNum<[23]>; -def r24 : GR< 24, "r24">, DwarfRegNum<[24]>; -def r25 : GR< 25, "r25">, DwarfRegNum<[25]>; -def r26 : GR< 26, "r26">, DwarfRegNum<[26]>; -def r27 : GR< 27, "r27">, DwarfRegNum<[27]>; -def r28 : GR< 28, "r28">, DwarfRegNum<[28]>; -def r29 : GR< 29, "r29">, DwarfRegNum<[29]>; -def r30 : GR< 30, "r30">, DwarfRegNum<[30]>; -def r31 : GR< 31, "r31">, DwarfRegNum<[31]>; -def r32 : GR< 32, "r32">, DwarfRegNum<[32]>; -def r33 : GR< 33, "r33">, DwarfRegNum<[33]>; -def r34 : GR< 34, "r34">, DwarfRegNum<[34]>; -def r35 : GR< 35, "r35">, DwarfRegNum<[35]>; -def r36 : GR< 36, "r36">, DwarfRegNum<[36]>; -def r37 : GR< 37, "r37">, DwarfRegNum<[37]>; -def r38 : GR< 38, "r38">, DwarfRegNum<[38]>; -def r39 : GR< 39, "r39">, DwarfRegNum<[39]>; -def r40 : GR< 40, "r40">, DwarfRegNum<[40]>; -def r41 : GR< 41, "r41">, DwarfRegNum<[41]>; -def r42 : GR< 42, "r42">, DwarfRegNum<[42]>; -def r43 : GR< 43, "r43">, DwarfRegNum<[43]>; -def r44 : GR< 44, "r44">, DwarfRegNum<[44]>; -def r45 : GR< 45, "r45">, DwarfRegNum<[45]>; -def r46 : GR< 46, "r46">, DwarfRegNum<[46]>; -def r47 : GR< 47, "r47">, DwarfRegNum<[47]>; -def r48 : GR< 48, "r48">, DwarfRegNum<[48]>; -def r49 : GR< 49, "r49">, DwarfRegNum<[49]>; -def r50 : GR< 50, "r50">, DwarfRegNum<[50]>; -def r51 : GR< 51, "r51">, DwarfRegNum<[51]>; -def r52 : GR< 52, "r52">, DwarfRegNum<[52]>; -def r53 : GR< 53, "r53">, DwarfRegNum<[53]>; -def r54 : GR< 54, "r54">, DwarfRegNum<[54]>; -def r55 : GR< 55, "r55">, DwarfRegNum<[55]>; -def r56 : GR< 56, "r56">, DwarfRegNum<[56]>; -def r57 : GR< 57, "r57">, DwarfRegNum<[57]>; -def r58 : GR< 58, "r58">, DwarfRegNum<[58]>; -def r59 : GR< 59, "r59">, DwarfRegNum<[59]>; -def r60 : GR< 60, "r60">, DwarfRegNum<[60]>; -def r61 : GR< 61, "r61">, DwarfRegNum<[61]>; -def r62 : GR< 62, "r62">, DwarfRegNum<[62]>; -def r63 : GR< 63, "r63">, DwarfRegNum<[63]>; -def r64 : GR< 64, "r64">, DwarfRegNum<[64]>; -def r65 : GR< 65, "r65">, DwarfRegNum<[65]>; -def r66 : GR< 66, "r66">, DwarfRegNum<[66]>; -def r67 : GR< 67, "r67">, DwarfRegNum<[67]>; -def r68 : GR< 68, "r68">, DwarfRegNum<[68]>; -def r69 : GR< 69, "r69">, DwarfRegNum<[69]>; -def r70 : GR< 70, "r70">, DwarfRegNum<[70]>; -def r71 : GR< 71, "r71">, DwarfRegNum<[71]>; -def r72 : GR< 72, "r72">, DwarfRegNum<[72]>; -def r73 : GR< 73, "r73">, DwarfRegNum<[73]>; -def r74 : GR< 74, "r74">, DwarfRegNum<[74]>; -def r75 : GR< 75, "r75">, DwarfRegNum<[75]>; -def r76 : GR< 76, "r76">, DwarfRegNum<[76]>; -def r77 : GR< 77, "r77">, DwarfRegNum<[77]>; -def r78 : GR< 78, "r78">, DwarfRegNum<[78]>; -def r79 : GR< 79, "r79">, DwarfRegNum<[79]>; -def r80 : GR< 80, "r80">, DwarfRegNum<[80]>; -def r81 : GR< 81, "r81">, DwarfRegNum<[81]>; -def r82 : GR< 82, "r82">, DwarfRegNum<[82]>; -def r83 : GR< 83, "r83">, DwarfRegNum<[83]>; -def r84 : GR< 84, "r84">, DwarfRegNum<[84]>; -def r85 : GR< 85, "r85">, DwarfRegNum<[85]>; -def r86 : GR< 86, "r86">, DwarfRegNum<[86]>; -def r87 : GR< 87, "r87">, DwarfRegNum<[87]>; -def r88 : GR< 88, "r88">, DwarfRegNum<[88]>; -def r89 : GR< 89, "r89">, DwarfRegNum<[89]>; -def r90 : GR< 90, "r90">, DwarfRegNum<[90]>; -def r91 : GR< 91, "r91">, DwarfRegNum<[91]>; -def r92 : GR< 92, "r92">, DwarfRegNum<[92]>; -def r93 : GR< 93, "r93">, DwarfRegNum<[93]>; -def r94 : GR< 94, "r94">, DwarfRegNum<[94]>; -def r95 : GR< 95, "r95">, DwarfRegNum<[95]>; -def r96 : GR< 96, "r96">, DwarfRegNum<[96]>; -def r97 : GR< 97, "r97">, DwarfRegNum<[97]>; -def r98 : GR< 98, "r98">, DwarfRegNum<[98]>; -def r99 : GR< 99, "r99">, DwarfRegNum<[99]>; -def r100 : GR< 100, "r100">, DwarfRegNum<[100]>; -def r101 : GR< 101, "r101">, DwarfRegNum<[101]>; -def r102 : GR< 102, "r102">, DwarfRegNum<[102]>; -def r103 : GR< 103, "r103">, DwarfRegNum<[103]>; -def r104 : GR< 104, "r104">, DwarfRegNum<[104]>; -def r105 : GR< 105, "r105">, DwarfRegNum<[105]>; -def r106 : GR< 106, "r106">, DwarfRegNum<[106]>; -def r107 : GR< 107, "r107">, DwarfRegNum<[107]>; -def r108 : GR< 108, "r108">, DwarfRegNum<[108]>; -def r109 : GR< 109, "r109">, DwarfRegNum<[109]>; -def r110 : GR< 110, "r110">, DwarfRegNum<[110]>; -def r111 : GR< 111, "r111">, DwarfRegNum<[111]>; -def r112 : GR< 112, "r112">, DwarfRegNum<[112]>; -def r113 : GR< 113, "r113">, DwarfRegNum<[113]>; -def r114 : GR< 114, "r114">, DwarfRegNum<[114]>; -def r115 : GR< 115, "r115">, DwarfRegNum<[115]>; -def r116 : GR< 116, "r116">, DwarfRegNum<[116]>; -def r117 : GR< 117, "r117">, DwarfRegNum<[117]>; -def r118 : GR< 118, "r118">, DwarfRegNum<[118]>; -def r119 : GR< 119, "r119">, DwarfRegNum<[119]>; -def r120 : GR< 120, "r120">, DwarfRegNum<[120]>; -def r121 : GR< 121, "r121">, DwarfRegNum<[121]>; -def r122 : GR< 122, "r122">, DwarfRegNum<[122]>; -def r123 : GR< 123, "r123">, DwarfRegNum<[123]>; -def r124 : GR< 124, "r124">, DwarfRegNum<[124]>; -def r125 : GR< 125, "r125">, DwarfRegNum<[125]>; -def r126 : GR< 126, "r126">, DwarfRegNum<[126]>; -def r127 : GR< 127, "r127">, DwarfRegNum<[127]>; - -/* floating-point registers */ -def F0 : FP< 0, "f0">, DwarfRegNum<[128]>; -def F1 : FP< 1, "f1">, DwarfRegNum<[129]>; -def F2 : FP< 2, "f2">, DwarfRegNum<[130]>; -def F3 : FP< 3, "f3">, DwarfRegNum<[131]>; -def F4 : FP< 4, "f4">, DwarfRegNum<[132]>; -def F5 : FP< 5, "f5">, DwarfRegNum<[133]>; -def F6 : FP< 6, "f6">, DwarfRegNum<[134]>; -def F7 : FP< 7, "f7">, DwarfRegNum<[135]>; -def F8 : FP< 8, "f8">, DwarfRegNum<[136]>; -def F9 : FP< 9, "f9">, DwarfRegNum<[137]>; -def F10 : FP< 10, "f10">, DwarfRegNum<[138]>; -def F11 : FP< 11, "f11">, DwarfRegNum<[139]>; -def F12 : FP< 12, "f12">, DwarfRegNum<[140]>; -def F13 : FP< 13, "f13">, DwarfRegNum<[141]>; -def F14 : FP< 14, "f14">, DwarfRegNum<[142]>; -def F15 : FP< 15, "f15">, DwarfRegNum<[143]>; -def F16 : FP< 16, "f16">, DwarfRegNum<[144]>; -def F17 : FP< 17, "f17">, DwarfRegNum<[145]>; -def F18 : FP< 18, "f18">, DwarfRegNum<[146]>; -def F19 : FP< 19, "f19">, DwarfRegNum<[147]>; -def F20 : FP< 20, "f20">, DwarfRegNum<[148]>; -def F21 : FP< 21, "f21">, DwarfRegNum<[149]>; -def F22 : FP< 22, "f22">, DwarfRegNum<[150]>; -def F23 : FP< 23, "f23">, DwarfRegNum<[151]>; -def F24 : FP< 24, "f24">, DwarfRegNum<[152]>; -def F25 : FP< 25, "f25">, DwarfRegNum<[153]>; -def F26 : FP< 26, "f26">, DwarfRegNum<[154]>; -def F27 : FP< 27, "f27">, DwarfRegNum<[155]>; -def F28 : FP< 28, "f28">, DwarfRegNum<[156]>; -def F29 : FP< 29, "f29">, DwarfRegNum<[157]>; -def F30 : FP< 30, "f30">, DwarfRegNum<[158]>; -def F31 : FP< 31, "f31">, DwarfRegNum<[159]>; -def F32 : FP< 32, "f32">, DwarfRegNum<[160]>; -def F33 : FP< 33, "f33">, DwarfRegNum<[161]>; -def F34 : FP< 34, "f34">, DwarfRegNum<[162]>; -def F35 : FP< 35, "f35">, DwarfRegNum<[163]>; -def F36 : FP< 36, "f36">, DwarfRegNum<[164]>; -def F37 : FP< 37, "f37">, DwarfRegNum<[165]>; -def F38 : FP< 38, "f38">, DwarfRegNum<[166]>; -def F39 : FP< 39, "f39">, DwarfRegNum<[167]>; -def F40 : FP< 40, "f40">, DwarfRegNum<[168]>; -def F41 : FP< 41, "f41">, DwarfRegNum<[169]>; -def F42 : FP< 42, "f42">, DwarfRegNum<[170]>; -def F43 : FP< 43, "f43">, DwarfRegNum<[171]>; -def F44 : FP< 44, "f44">, DwarfRegNum<[172]>; -def F45 : FP< 45, "f45">, DwarfRegNum<[173]>; -def F46 : FP< 46, "f46">, DwarfRegNum<[174]>; -def F47 : FP< 47, "f47">, DwarfRegNum<[175]>; -def F48 : FP< 48, "f48">, DwarfRegNum<[176]>; -def F49 : FP< 49, "f49">, DwarfRegNum<[177]>; -def F50 : FP< 50, "f50">, DwarfRegNum<[178]>; -def F51 : FP< 51, "f51">, DwarfRegNum<[179]>; -def F52 : FP< 52, "f52">, DwarfRegNum<[180]>; -def F53 : FP< 53, "f53">, DwarfRegNum<[181]>; -def F54 : FP< 54, "f54">, DwarfRegNum<[182]>; -def F55 : FP< 55, "f55">, DwarfRegNum<[183]>; -def F56 : FP< 56, "f56">, DwarfRegNum<[184]>; -def F57 : FP< 57, "f57">, DwarfRegNum<[185]>; -def F58 : FP< 58, "f58">, DwarfRegNum<[186]>; -def F59 : FP< 59, "f59">, DwarfRegNum<[187]>; -def F60 : FP< 60, "f60">, DwarfRegNum<[188]>; -def F61 : FP< 61, "f61">, DwarfRegNum<[189]>; -def F62 : FP< 62, "f62">, DwarfRegNum<[190]>; -def F63 : FP< 63, "f63">, DwarfRegNum<[191]>; -def F64 : FP< 64, "f64">, DwarfRegNum<[192]>; -def F65 : FP< 65, "f65">, DwarfRegNum<[193]>; -def F66 : FP< 66, "f66">, DwarfRegNum<[194]>; -def F67 : FP< 67, "f67">, DwarfRegNum<[195]>; -def F68 : FP< 68, "f68">, DwarfRegNum<[196]>; -def F69 : FP< 69, "f69">, DwarfRegNum<[197]>; -def F70 : FP< 70, "f70">, DwarfRegNum<[198]>; -def F71 : FP< 71, "f71">, DwarfRegNum<[199]>; -def F72 : FP< 72, "f72">, DwarfRegNum<[200]>; -def F73 : FP< 73, "f73">, DwarfRegNum<[201]>; -def F74 : FP< 74, "f74">, DwarfRegNum<[202]>; -def F75 : FP< 75, "f75">, DwarfRegNum<[203]>; -def F76 : FP< 76, "f76">, DwarfRegNum<[204]>; -def F77 : FP< 77, "f77">, DwarfRegNum<[205]>; -def F78 : FP< 78, "f78">, DwarfRegNum<[206]>; -def F79 : FP< 79, "f79">, DwarfRegNum<[207]>; -def F80 : FP< 80, "f80">, DwarfRegNum<[208]>; -def F81 : FP< 81, "f81">, DwarfRegNum<[209]>; -def F82 : FP< 82, "f82">, DwarfRegNum<[210]>; -def F83 : FP< 83, "f83">, DwarfRegNum<[211]>; -def F84 : FP< 84, "f84">, DwarfRegNum<[212]>; -def F85 : FP< 85, "f85">, DwarfRegNum<[213]>; -def F86 : FP< 86, "f86">, DwarfRegNum<[214]>; -def F87 : FP< 87, "f87">, DwarfRegNum<[215]>; -def F88 : FP< 88, "f88">, DwarfRegNum<[216]>; -def F89 : FP< 89, "f89">, DwarfRegNum<[217]>; -def F90 : FP< 90, "f90">, DwarfRegNum<[218]>; -def F91 : FP< 91, "f91">, DwarfRegNum<[219]>; -def F92 : FP< 92, "f92">, DwarfRegNum<[220]>; -def F93 : FP< 93, "f93">, DwarfRegNum<[221]>; -def F94 : FP< 94, "f94">, DwarfRegNum<[222]>; -def F95 : FP< 95, "f95">, DwarfRegNum<[223]>; -def F96 : FP< 96, "f96">, DwarfRegNum<[224]>; -def F97 : FP< 97, "f97">, DwarfRegNum<[225]>; -def F98 : FP< 98, "f98">, DwarfRegNum<[226]>; -def F99 : FP< 99, "f99">, DwarfRegNum<[227]>; -def F100 : FP< 100, "f100">, DwarfRegNum<[228]>; -def F101 : FP< 101, "f101">, DwarfRegNum<[229]>; -def F102 : FP< 102, "f102">, DwarfRegNum<[230]>; -def F103 : FP< 103, "f103">, DwarfRegNum<[231]>; -def F104 : FP< 104, "f104">, DwarfRegNum<[232]>; -def F105 : FP< 105, "f105">, DwarfRegNum<[233]>; -def F106 : FP< 106, "f106">, DwarfRegNum<[234]>; -def F107 : FP< 107, "f107">, DwarfRegNum<[235]>; -def F108 : FP< 108, "f108">, DwarfRegNum<[236]>; -def F109 : FP< 109, "f109">, DwarfRegNum<[237]>; -def F110 : FP< 110, "f110">, DwarfRegNum<[238]>; -def F111 : FP< 111, "f111">, DwarfRegNum<[239]>; -def F112 : FP< 112, "f112">, DwarfRegNum<[240]>; -def F113 : FP< 113, "f113">, DwarfRegNum<[241]>; -def F114 : FP< 114, "f114">, DwarfRegNum<[242]>; -def F115 : FP< 115, "f115">, DwarfRegNum<[243]>; -def F116 : FP< 116, "f116">, DwarfRegNum<[244]>; -def F117 : FP< 117, "f117">, DwarfRegNum<[245]>; -def F118 : FP< 118, "f118">, DwarfRegNum<[246]>; -def F119 : FP< 119, "f119">, DwarfRegNum<[247]>; -def F120 : FP< 120, "f120">, DwarfRegNum<[248]>; -def F121 : FP< 121, "f121">, DwarfRegNum<[249]>; -def F122 : FP< 122, "f122">, DwarfRegNum<[250]>; -def F123 : FP< 123, "f123">, DwarfRegNum<[251]>; -def F124 : FP< 124, "f124">, DwarfRegNum<[252]>; -def F125 : FP< 125, "f125">, DwarfRegNum<[253]>; -def F126 : FP< 126, "f126">, DwarfRegNum<[254]>; -def F127 : FP< 127, "f127">, DwarfRegNum<[255]>; - -/* predicate registers */ -def p0 : PR< 0, "p0">, DwarfRegNum<[256]>; -def p1 : PR< 1, "p1">, DwarfRegNum<[257]>; -def p2 : PR< 2, "p2">, DwarfRegNum<[258]>; -def p3 : PR< 3, "p3">, DwarfRegNum<[259]>; -def p4 : PR< 4, "p4">, DwarfRegNum<[260]>; -def p5 : PR< 5, "p5">, DwarfRegNum<[261]>; -def p6 : PR< 6, "p6">, DwarfRegNum<[262]>; -def p7 : PR< 7, "p7">, DwarfRegNum<[263]>; -def p8 : PR< 8, "p8">, DwarfRegNum<[264]>; -def p9 : PR< 9, "p9">, DwarfRegNum<[265]>; -def p10 : PR< 10, "p10">, DwarfRegNum<[266]>; -def p11 : PR< 11, "p11">, DwarfRegNum<[267]>; -def p12 : PR< 12, "p12">, DwarfRegNum<[268]>; -def p13 : PR< 13, "p13">, DwarfRegNum<[269]>; -def p14 : PR< 14, "p14">, DwarfRegNum<[270]>; -def p15 : PR< 15, "p15">, DwarfRegNum<[271]>; -def p16 : PR< 16, "p16">, DwarfRegNum<[272]>; -def p17 : PR< 17, "p17">, DwarfRegNum<[273]>; -def p18 : PR< 18, "p18">, DwarfRegNum<[274]>; -def p19 : PR< 19, "p19">, DwarfRegNum<[275]>; -def p20 : PR< 20, "p20">, DwarfRegNum<[276]>; -def p21 : PR< 21, "p21">, DwarfRegNum<[277]>; -def p22 : PR< 22, "p22">, DwarfRegNum<[278]>; -def p23 : PR< 23, "p23">, DwarfRegNum<[279]>; -def p24 : PR< 24, "p24">, DwarfRegNum<[280]>; -def p25 : PR< 25, "p25">, DwarfRegNum<[281]>; -def p26 : PR< 26, "p26">, DwarfRegNum<[282]>; -def p27 : PR< 27, "p27">, DwarfRegNum<[283]>; -def p28 : PR< 28, "p28">, DwarfRegNum<[284]>; -def p29 : PR< 29, "p29">, DwarfRegNum<[285]>; -def p30 : PR< 30, "p30">, DwarfRegNum<[286]>; -def p31 : PR< 31, "p31">, DwarfRegNum<[287]>; -def p32 : PR< 32, "p32">, DwarfRegNum<[288]>; -def p33 : PR< 33, "p33">, DwarfRegNum<[289]>; -def p34 : PR< 34, "p34">, DwarfRegNum<[290]>; -def p35 : PR< 35, "p35">, DwarfRegNum<[291]>; -def p36 : PR< 36, "p36">, DwarfRegNum<[292]>; -def p37 : PR< 37, "p37">, DwarfRegNum<[293]>; -def p38 : PR< 38, "p38">, DwarfRegNum<[294]>; -def p39 : PR< 39, "p39">, DwarfRegNum<[295]>; -def p40 : PR< 40, "p40">, DwarfRegNum<[296]>; -def p41 : PR< 41, "p41">, DwarfRegNum<[297]>; -def p42 : PR< 42, "p42">, DwarfRegNum<[298]>; -def p43 : PR< 43, "p43">, DwarfRegNum<[299]>; -def p44 : PR< 44, "p44">, DwarfRegNum<[300]>; -def p45 : PR< 45, "p45">, DwarfRegNum<[301]>; -def p46 : PR< 46, "p46">, DwarfRegNum<[302]>; -def p47 : PR< 47, "p47">, DwarfRegNum<[303]>; -def p48 : PR< 48, "p48">, DwarfRegNum<[304]>; -def p49 : PR< 49, "p49">, DwarfRegNum<[305]>; -def p50 : PR< 50, "p50">, DwarfRegNum<[306]>; -def p51 : PR< 51, "p51">, DwarfRegNum<[307]>; -def p52 : PR< 52, "p52">, DwarfRegNum<[308]>; -def p53 : PR< 53, "p53">, DwarfRegNum<[309]>; -def p54 : PR< 54, "p54">, DwarfRegNum<[310]>; -def p55 : PR< 55, "p55">, DwarfRegNum<[311]>; -def p56 : PR< 56, "p56">, DwarfRegNum<[312]>; -def p57 : PR< 57, "p57">, DwarfRegNum<[313]>; -def p58 : PR< 58, "p58">, DwarfRegNum<[314]>; -def p59 : PR< 59, "p59">, DwarfRegNum<[315]>; -def p60 : PR< 60, "p60">, DwarfRegNum<[316]>; -def p61 : PR< 61, "p61">, DwarfRegNum<[317]>; -def p62 : PR< 62, "p62">, DwarfRegNum<[318]>; -def p63 : PR< 63, "p63">, DwarfRegNum<[319]>; - -// XXX : this is temporary, we'll eventually have the output registers -// in the general purpose register class too? -def out0 : GR<0, "out0">, DwarfRegNum<[120]>; -def out1 : GR<1, "out1">, DwarfRegNum<[121]>; -def out2 : GR<2, "out2">, DwarfRegNum<[122]>; -def out3 : GR<3, "out3">, DwarfRegNum<[123]>; -def out4 : GR<4, "out4">, DwarfRegNum<[124]>; -def out5 : GR<5, "out5">, DwarfRegNum<[125]>; -def out6 : GR<6, "out6">, DwarfRegNum<[126]>; -def out7 : GR<7, "out7">, DwarfRegNum<[127]>; - -// application (special) registers: - -// "previous function state" application register -def AR_PFS : GR<0, "ar.pfs">, DwarfRegNum<[331]>; - -// "return pointer" (this is really branch register b0) -def rp : GR<0, "rp">, DwarfRegNum<[-1]>; - -// branch reg 6 -def B6 : GR<0, "b6">, DwarfRegNum<[326]>; - -//===----------------------------------------------------------------------===// -// Register Class Definitions... now that we have all of the pieces, define the -// top-level register classes. The order specified in the register list is -// implicitly defined to be the register allocation order. -// - -// these are the scratch (+stacked) general registers -// FIXME/XXX we also reserve a frame pointer (r5) -// FIXME/XXX we also reserve r2 for spilling/filling predicates -// in IA64RegisterInfo.cpp -// FIXME/XXX we also reserve r22 for calculating addresses -// in IA64RegisterInfo.cpp - -def GR : RegisterClass<"IA64", [i64], 64, - [ - -//FIXME!: for both readability and performance, we don't want the out -// registers to be the first ones allocated - - out7, out6, out5, out4, out3, out2, out1, out0, - r3, r8, r9, r10, r11, r14, r15, - r16, r17, r18, r19, r20, r21, r23, - r24, r25, r26, r27, r28, r29, r30, r31, - r32, r33, r34, r35, r36, r37, r38, r39, - r40, r41, r42, r43, r44, r45, r46, r47, - r48, r49, r50, r51, r52, r53, r54, r55, - r56, r57, r58, r59, r60, r61, r62, r63, - r64, r65, r66, r67, r68, r69, r70, r71, - r72, r73, r74, r75, r76, r77, r78, r79, - r80, r81, r82, r83, r84, r85, r86, r87, - r88, r89, r90, r91, r92, r93, r94, r95, - r96, r97, r98, r99, r100, r101, r102, r103, - r104, r105, r106, r107, r108, r109, r110, r111, - r112, r113, r114, r115, r116, r117, r118, r119, - // last 17 are special (look down) - r120, r121, r122, r123, r124, r125, r126, r127, - r0, r1, r2, r5, r12, r13, r22, rp, AR_PFS]> - { - let MethodProtos = [{ - iterator allocation_order_begin(const MachineFunction &MF) const; - iterator allocation_order_end(const MachineFunction &MF) const; - }]; - let MethodBodies = [{ - GRClass::iterator - GRClass::allocation_order_begin(const MachineFunction &MF) const { - // hide the 8 out? registers appropriately: - return begin()+(8-(MF.getInfo<IA64FunctionInfo>()->outRegsUsed)); - } - - GRClass::iterator - GRClass::allocation_order_end(const MachineFunction &MF) const { - // the 9 special registers r0,r1,r2,r5,r12,r13 etc - int numReservedRegs=9; - - // we also can't allocate registers for use as locals if they're already - // required as 'out' registers - numReservedRegs+=MF.getInfo<IA64FunctionInfo>()->outRegsUsed; - return end()-numReservedRegs; // hide registers appropriately - } - }]; -} - - -// these are the scratch (+stacked) FP registers - -def FP : RegisterClass<"IA64", [f64], 64, - [F6, F7, - F8, F9, F10, F11, F12, F13, F14, F15, - F32, F33, F34, F35, F36, F37, F38, F39, - F40, F41, F42, F43, F44, F45, F46, F47, - F48, F49, F50, F51, F52, F53, F54, F55, - F56, F57, F58, F59, F60, F61, F62, F63, - F64, F65, F66, F67, F68, F69, F70, F71, - F72, F73, F74, F75, F76, F77, F78, F79, - F80, F81, F82, F83, F84, F85, F86, F87, - F88, F89, F90, F91, F92, F93, F94, F95, - F96, F97, F98, F99, F100, F101, F102, F103, - F104, F105, F106, F107, F108, F109, F110, F111, - F112, F113, F114, F115, F116, F117, F118, F119, - F120, F121, F122, F123, F124, F125, F126, F127, - F0, F1]> // these last two are hidden - { -// the 128s here are to make stf.spill/ldf.fill happy, -// when storing full (82-bit) FP regs to stack slots -// we need to 16-byte align - let Size=128; - let Alignment=128; - - let MethodProtos = [{ - iterator allocation_order_begin(const MachineFunction &MF) const; - iterator allocation_order_end(const MachineFunction &MF) const; - }]; - let MethodBodies = [{ - FPClass::iterator - FPClass::allocation_order_begin(const MachineFunction &MF) const { - return begin(); // we don't hide any FP regs from the start - } - - FPClass::iterator - FPClass::allocation_order_end(const MachineFunction &MF) const { - return end()-2; // we hide regs F0, F1 from the end - } - }]; -} - -// these are the predicate registers, p0 (1/TRUE) is not here -def PR : RegisterClass<"IA64", [i1], 64, - -// for now, let's be wimps and only have the scratch predicate regs - [p6, p7, p8, p9, p10, p11, p12, p13, p14, p15]> { - let Size = 64; - } - -/* - [p1, p2, p3, p4, p5, p6, p7, - p8, p9, p10, p11, p12, p13, p14, p15, - p16, p17, p18, p19, p20, p21, p22, p23, - p24, p25, p26, p27, p28, p29, p30, p31, - p32, p33, p34, p35, p36, p37, p38, p39, - p40, p41, p42, p43, p44, p45, p46, p47, - p48, p49, p50, p51, p52, p53, p54, p55, - p56, p57, p58, p59, p60, p61, p62, p63]>; - */ diff --git a/lib/Target/IA64/IA64Subtarget.cpp b/lib/Target/IA64/IA64Subtarget.cpp deleted file mode 100644 index 4eca50b..0000000 --- a/lib/Target/IA64/IA64Subtarget.cpp +++ /dev/null @@ -1,18 +0,0 @@ -//===-- IA64Subtarget.cpp - IA64 Subtarget Information ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the IA64 specific subclass of TargetSubtarget. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "subtarget" -#include "IA64Subtarget.h" -using namespace llvm; - -IA64Subtarget::IA64Subtarget() {} diff --git a/lib/Target/IA64/IA64Subtarget.h b/lib/Target/IA64/IA64Subtarget.h deleted file mode 100644 index 0387af5..0000000 --- a/lib/Target/IA64/IA64Subtarget.h +++ /dev/null @@ -1,28 +0,0 @@ -//====---- IA64Subtarget.h - Define Subtarget for the IA64 -----*- C++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the IA64 specific subclass of TargetSubtarget. -// -//===----------------------------------------------------------------------===// - -#ifndef IA64SUBTARGET_H -#define IA64SUBTARGET_H - -#include "llvm/Target/TargetSubtarget.h" - -namespace llvm { - -class IA64Subtarget : public TargetSubtarget { -public: - IA64Subtarget(); -}; - -} // End llvm namespace - -#endif diff --git a/lib/Target/IA64/IA64TargetAsmInfo.cpp b/lib/Target/IA64/IA64TargetAsmInfo.cpp deleted file mode 100644 index 2ae8beb..0000000 --- a/lib/Target/IA64/IA64TargetAsmInfo.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//===-- IA64TargetAsmInfo.cpp - IA64 asm properties -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the IA64TargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "IA64TargetAsmInfo.h" -#include "llvm/Constants.h" -#include "llvm/Target/TargetMachine.h" - -using namespace llvm; - -IA64TargetAsmInfo::IA64TargetAsmInfo(const TargetMachine &TM): - ELFTargetAsmInfo(TM) { - CommentString = "//"; - Data8bitsDirective = "\tdata1\t"; // FIXME: check that we are - Data16bitsDirective = "\tdata2.ua\t"; // disabling auto-alignment - Data32bitsDirective = "\tdata4.ua\t"; // properly - Data64bitsDirective = "\tdata8.ua\t"; - ZeroDirective = "\t.skip\t"; - AsciiDirective = "\tstring\t"; - - GlobalVarAddrPrefix=""; - GlobalVarAddrSuffix=""; - FunctionAddrPrefix="@fptr("; - FunctionAddrSuffix=")"; - - // FIXME: would be nice to have rodata (no 'w') when appropriate? - ConstantPoolSection = "\n\t.section .data, \"aw\", \"progbits\"\n"; -} - -unsigned IA64TargetAsmInfo::RelocBehaviour() const { - return (TM.getRelocationModel() != Reloc::Static ? - Reloc::LocalOrGlobal : Reloc::Global); -} - -// FIXME: Support small data/bss/rodata sections someday. diff --git a/lib/Target/IA64/IA64TargetAsmInfo.h b/lib/Target/IA64/IA64TargetAsmInfo.h deleted file mode 100644 index 130822e..0000000 --- a/lib/Target/IA64/IA64TargetAsmInfo.h +++ /dev/null @@ -1,33 +0,0 @@ -//=====-- IA64TargetAsmInfo.h - IA64 asm properties -----------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the IA64TargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef IA64TARGETASMINFO_H -#define IA64TARGETASMINFO_H - -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" - -namespace llvm { - - // Forward declaration. - class TargetMachine; - - struct IA64TargetAsmInfo : public ELFTargetAsmInfo { - explicit IA64TargetAsmInfo(const TargetMachine &TM); - virtual unsigned RelocBehaviour() const; - }; - - -} // namespace llvm - -#endif diff --git a/lib/Target/IA64/IA64TargetMachine.cpp b/lib/Target/IA64/IA64TargetMachine.cpp deleted file mode 100644 index 71a0a98..0000000 --- a/lib/Target/IA64/IA64TargetMachine.cpp +++ /dev/null @@ -1,97 +0,0 @@ -//===-- IA64TargetMachine.cpp - Define TargetMachine for IA64 -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the IA64 specific subclass of TargetMachine. -// -//===----------------------------------------------------------------------===// - -#include "IA64TargetAsmInfo.h" -#include "IA64TargetMachine.h" -#include "IA64.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Target/TargetMachineRegistry.h" -using namespace llvm; - -// Register the target -static RegisterTarget<IA64TargetMachine> X("ia64", - "IA-64 (Itanium) [experimental]"); - -// No assembler printer by default -IA64TargetMachine::AsmPrinterCtorFn IA64TargetMachine::AsmPrinterCtor = 0; - -// Force static initialization. -extern "C" void LLVMInitializeIA64Target() { } - -const TargetAsmInfo *IA64TargetMachine::createTargetAsmInfo() const { - return new IA64TargetAsmInfo(*this); -} - -unsigned IA64TargetMachine::getModuleMatchQuality(const Module &M) { - // we match [iI][aA]*64 - bool seenIA64=false; - std::string TT = M.getTargetTriple(); - - if (TT.size() >= 4) { - if( (TT[0]=='i' || TT[0]=='I') && - (TT[1]=='a' || TT[1]=='A') ) { - for(unsigned int i=2; i<(TT.size()-1); i++) - if(TT[i]=='6' && TT[i+1]=='4') - seenIA64=true; - } - - if (seenIA64) - return 20; // strong match - } - // If the target triple is something non-ia64, we don't match. - if (!TT.empty()) return 0; - -#if defined(__ia64__) || defined(__IA64__) - return 5; -#else - return 0; -#endif -} - -/// IA64TargetMachine ctor - Create an LP64 architecture model -/// -IA64TargetMachine::IA64TargetMachine(const Module &M, const std::string &FS) - : DataLayout("e-f80:128:128"), - FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), - TLInfo(*this) { // FIXME? check this stuff -} - - -//===----------------------------------------------------------------------===// -// Pass Pipeline Configuration -//===----------------------------------------------------------------------===// - -bool IA64TargetMachine::addInstSelector(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { - PM.add(createIA64DAGToDAGInstructionSelector(*this)); - return false; -} - -bool IA64TargetMachine::addPreEmitPass(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { - // Make sure everything is bundled happily - PM.add(createIA64BundlingPass(*this)); - return true; -} -bool IA64TargetMachine::addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, - raw_ostream &Out) { - // Output assembly language. - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(Out, *this, Verbose)); - return false; -} - diff --git a/lib/Target/IA64/IA64TargetMachine.h b/lib/Target/IA64/IA64TargetMachine.h deleted file mode 100644 index 402d833..0000000 --- a/lib/Target/IA64/IA64TargetMachine.h +++ /dev/null @@ -1,75 +0,0 @@ -//===-- IA64TargetMachine.h - Define TargetMachine for IA64 ---*- C++ -*---===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the IA64 specific subclass of TargetMachine. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_IA64TARGETMACHINE_H -#define LLVM_TARGET_IA64TARGETMACHINE_H - -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "IA64InstrInfo.h" -#include "IA64ISelLowering.h" -#include "IA64Subtarget.h" - -namespace llvm { - -class IA64TargetMachine : public LLVMTargetMachine { - IA64Subtarget Subtarget; - const TargetData DataLayout; // Calculates type size & alignment - IA64InstrInfo InstrInfo; - TargetFrameInfo FrameInfo; - //IA64JITInfo JITInfo; - IA64TargetLowering TLInfo; - -protected: - virtual const TargetAsmInfo *createTargetAsmInfo() const; - - // To avoid having target depend on the asmprinter stuff libraries, asmprinter - // set this functions to ctor pointer at startup time if they are linked in. - typedef FunctionPass *(*AsmPrinterCtorFn)(raw_ostream &o, - IA64TargetMachine &tm, - bool verbose); - static AsmPrinterCtorFn AsmPrinterCtor; - -public: - IA64TargetMachine(const Module &M, const std::string &FS); - - virtual const IA64InstrInfo *getInstrInfo() const { return &InstrInfo; } - virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } - virtual const IA64Subtarget *getSubtargetImpl() const { return &Subtarget; } - virtual IA64TargetLowering *getTargetLowering() const { - return const_cast<IA64TargetLowering*>(&TLInfo); - } - virtual const IA64RegisterInfo *getRegisterInfo() const { - return &InstrInfo.getRegisterInfo(); - } - virtual const TargetData *getTargetData() const { return &DataLayout; } - - static unsigned getModuleMatchQuality(const Module &M); - - // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); - virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel); - virtual bool addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, raw_ostream &Out); - - static void registerAsmPrinter(AsmPrinterCtorFn F) { - AsmPrinterCtor = F; - } -}; -} // End llvm namespace - -#endif - - diff --git a/lib/Target/IA64/Makefile b/lib/Target/IA64/Makefile deleted file mode 100644 index d383254..0000000 --- a/lib/Target/IA64/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -##===- lib/Target/IA64/Makefile -----------------------------*- Makefile -*-===## -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../.. -LIBRARYNAME = LLVMIA64CodeGen -TARGET = IA64 -# Make sure that tblgen is run, first thing. -BUILT_SOURCES = IA64GenRegisterInfo.h.inc IA64GenRegisterNames.inc \ - IA64GenRegisterInfo.inc IA64GenInstrNames.inc \ - IA64GenInstrInfo.inc IA64GenAsmWriter.inc \ - IA64GenDAGISel.inc - -DIRS = AsmPrinter - -include $(LEVEL)/Makefile.common - diff --git a/lib/Target/IA64/README b/lib/Target/IA64/README deleted file mode 100644 index 60761ac..0000000 --- a/lib/Target/IA64/README +++ /dev/null @@ -1,48 +0,0 @@ -TODO: - - Un-bitrot ISel - - Hook up If-Conversion a la ARM target - - Hook up all branch analysis functions - - Instruction scheduling - - Bundling - - Dynamic Optimization - - Testing and bugfixing - - stop passing FP args in both FP *and* integer regs when not required - - allocate low (nonstacked) registers more aggressively - - clean up and thoroughly test the isel patterns. - - fix stacked register allocation order: (for readability) we don't want - the out? registers being the first ones used - - fix up floating point - (nb http://gcc.gnu.org/wiki?pagename=ia64%20floating%20point ) - - bundling! - (we will avoid the mess that is: - http://gcc.gnu.org/ml/gcc/2003-12/msg00832.html ) - - instruction scheduling (hmmmm! ;) - - counted loop support - - make integer + FP mul/div more clever (we have fixed pseudocode atm) - - track and use comparison complements - -INFO: - - we are strictly LP64 here, no support for ILP32 on HP-UX. Linux users - don't need to worry about this. - - i have instruction scheduling/bundling pseudocode, that really works - (has been tested, albeit at the perl-script level). - so, before you go write your own, send me an email! - -KNOWN DEFECTS AT THE CURRENT TIME: - - C++ vtables contain naked function pointers, not function descriptors, - which is bad. see http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=406 - - varargs are broken - - alloca doesn't work (indeed, stack frame layout is bogus) - - no support for big-endian environments - - (not really the backend, but...) the CFE has some issues on IA64. - these will probably be fixed soon. - -ACKNOWLEDGEMENTS: - - Chris Lattner (x100) - - Other LLVM developers ("hey, that looks familiar") - -CONTACT: - - You can email me at duraid@octopus.com.au. If you find a small bug, - just email me. If you find a big bug, please file a bug report - in bugzilla! http://llvm.cs.uiuc.edu is your one stop shop for all - things LLVM. diff --git a/lib/Target/MSP430/MSP430AsmPrinter.cpp b/lib/Target/MSP430/MSP430AsmPrinter.cpp deleted file mode 100644 index b1fa3f0..0000000 --- a/lib/Target/MSP430/MSP430AsmPrinter.cpp +++ /dev/null @@ -1,262 +0,0 @@ -//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ------------------===// -// -// 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 the MSP430 assembly language. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "MSP430.h" -#include "MSP430InstrInfo.h" -#include "MSP430TargetMachine.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -namespace { - class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter { - public: - MSP430AsmPrinter(raw_ostream &O, MSP430TargetMachine &TM, - const TargetAsmInfo *TAI, bool V) - : AsmPrinter(O, TM, TAI, V) {} - - virtual const char *getPassName() const { - return "MSP430 Assembly Printer"; - } - - void printOperand(const MachineInstr *MI, int OpNum, - const char* Modifier = 0); - void printSrcMemOperand(const MachineInstr *MI, int OpNum, - const char* Modifier = 0); - void printCCOperand(const MachineInstr *MI, int OpNum); - bool printInstruction(const MachineInstr *MI); // autogenerated. - void printMachineInstruction(const MachineInstr * MI); - - void emitFunctionHeader(const MachineFunction &MF); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - void getAnalysisUsage(AnalysisUsage &AU) const { - AsmPrinter::getAnalysisUsage(AU); - AU.setPreservesAll(); - } - }; -} // end of anonymous namespace - -#include "MSP430GenAsmWriter.inc" - -/// createMSP430CodePrinterPass - Returns a pass that prints the MSP430 -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createMSP430CodePrinterPass(raw_ostream &o, - MSP430TargetMachine &tm, - bool verbose) { - return new MSP430AsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); -} - -bool MSP430AsmPrinter::doInitialization(Module &M) { - Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix()); - return false; // success -} - - -bool MSP430AsmPrinter::doFinalization(Module &M) { - return AsmPrinter::doFinalization(M); -} - -void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) { - const Function *F = MF.getFunction(); - - SwitchToSection(TAI->SectionForGlobal(F)); - - unsigned FnAlign = MF.getAlignment(); - EmitAlignment(FnAlign, F); - - switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); - case Function::InternalLinkage: // Symbols default to internal. - case Function::PrivateLinkage: - break; - case Function::ExternalLinkage: - O << "\t.globl\t" << CurrentFnName << '\n'; - break; - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: - O << "\t.weak\t" << CurrentFnName << '\n'; - break; - } - - printVisibility(CurrentFnName, F->getVisibility()); - - O << "\t.type\t" << CurrentFnName << ",@function\n" - << CurrentFnName << ":\n"; -} - -bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) { - SetupMachineFunction(MF); - O << "\n\n"; - - // Print the 'header' of function - emitFunctionHeader(MF); - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) { - // This is an entry block or a block that's only reachable via a - // fallthrough edge. In non-VerboseAsm mode, don't print the label. - } else { - printBasicBlockLabel(I, true, true, VerboseAsm); - O << '\n'; - } - - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) - // Print the assembly for the instruction. - printMachineInstruction(II); - } - - if (TAI->hasDotTypeDotSizeDirective()) - O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; - - O.flush(); - - // We didn't modify anything - return false; -} - -void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - // Call the autogenerated instruction printer routines. - if (printInstruction(MI)) - return; - - assert(0 && "Should not happen"); -} - -void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum, - const char* Modifier) { - const MachineOperand &MO = MI->getOperand(OpNum); - switch (MO.getType()) { - case MachineOperand::MO_Register: - assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Virtual registers should be already mapped!"); - O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; - return; - case MachineOperand::MO_Immediate: - if (!Modifier || strcmp(Modifier, "nohash")) - O << '#'; - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; - case MachineOperand::MO_GlobalAddress: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - bool isCallOp = Modifier && !strcmp(Modifier, "call"); - std::string Name = Mang->getValueName(MO.getGlobal()); - assert(MO.getOffset() == 0 && "No offsets allowed!"); - - if (isCallOp) - O << '#'; - else if (isMemOp) - O << '&'; - - O << Name; - - return; - } - case MachineOperand::MO_ExternalSymbol: { - bool isCallOp = Modifier && !strcmp(Modifier, "call"); - std::string Name(TAI->getGlobalPrefix()); - Name += MO.getSymbolName(); - if (isCallOp) - O << '#'; - O << Name; - return; - } - default: - assert(0 && "Not implemented yet!"); - } -} - -void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum, - const char* Modifier) { - const MachineOperand &Base = MI->getOperand(OpNum); - const MachineOperand &Disp = MI->getOperand(OpNum+1); - - if (Base.isGlobal()) - printOperand(MI, OpNum, "mem"); - else if (Disp.isImm() && !Base.getReg()) - printOperand(MI, OpNum); - else if (Base.getReg()) { - if (Disp.getImm()) { - printOperand(MI, OpNum + 1, "nohash"); - O << '('; - printOperand(MI, OpNum); - O << ')'; - } else { - O << '@'; - printOperand(MI, OpNum); - } - } else - assert(0 && "Unsupported memory operand"); -} - -void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) { - unsigned CC = MI->getOperand(OpNum).getImm(); - - switch (CC) { - default: - assert(0 && "Unsupported CC code"); - break; - case MSP430::COND_E: - O << "eq"; - break; - case MSP430::COND_NE: - O << "ne"; - break; - case MSP430::COND_HS: - O << "hs"; - break; - case MSP430::COND_LO: - O << "lo"; - break; - case MSP430::COND_GE: - O << "ge"; - break; - case MSP430::COND_L: - O << 'l'; - break; - } -} diff --git a/lib/Target/MSP430/MSP430TargetAsmInfo.cpp b/lib/Target/MSP430/MSP430TargetAsmInfo.cpp deleted file mode 100644 index ab181de..0000000 --- a/lib/Target/MSP430/MSP430TargetAsmInfo.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===-- MSP430TargetAsmInfo.cpp - MSP430 asm properties -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the MSP430TargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "MSP430TargetAsmInfo.h" -#include "MSP430TargetMachine.h" - -using namespace llvm; - -MSP430TargetAsmInfo::MSP430TargetAsmInfo(const MSP430TargetMachine &TM) - : ELFTargetAsmInfo(TM) { - AlignmentIsInBytes = false; -} diff --git a/lib/Target/MSP430/MSP430TargetAsmInfo.h b/lib/Target/MSP430/MSP430TargetAsmInfo.h deleted file mode 100644 index b58d5c9..0000000 --- a/lib/Target/MSP430/MSP430TargetAsmInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -//=====-- MSP430TargetAsmInfo.h - MSP430 asm properties -------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the MSP430TargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef MSP430TARGETASMINFO_H -#define MSP430TARGETASMINFO_H - -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" - -namespace llvm { - - // Forward declaration. - class MSP430TargetMachine; - - struct MSP430TargetAsmInfo : public ELFTargetAsmInfo { - explicit MSP430TargetAsmInfo(const MSP430TargetMachine &TM); - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp deleted file mode 100644 index c197b0c..0000000 --- a/lib/Target/Mips/MipsTargetAsmInfo.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//===-- MipsTargetAsmInfo.cpp - Mips asm properties -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the MipsTargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "MipsTargetAsmInfo.h" -#include "MipsTargetMachine.h" -#include "llvm/GlobalVariable.h" - -using namespace llvm; - -MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM): - ELFTargetAsmInfo(TM) { - - Subtarget = &TM.getSubtarget<MipsSubtarget>(); - - AlignmentIsInBytes = false; - COMMDirectiveTakesAlignment = true; - Data16bitsDirective = "\t.half\t"; - Data32bitsDirective = "\t.word\t"; - Data64bitsDirective = NULL; - PrivateGlobalPrefix = "$"; - JumpTableDataSection = "\t.rdata"; - CommentString = "#"; - ZeroDirective = "\t.space\t"; - BSSSection = "\t.section\t.bss"; - CStringSection = ".rodata.str"; - - if (!Subtarget->hasABICall()) { - JumpTableDirective = "\t.word\t"; - SmallDataSection = getNamedSection("\t.sdata", SectionFlags::Writeable); - SmallBSSSection = getNamedSection("\t.sbss", - SectionFlags::Writeable | - SectionFlags::BSS); - } else - JumpTableDirective = "\t.gpword\t"; - -} - -unsigned MipsTargetAsmInfo:: -SectionFlagsForGlobal(const GlobalValue *GV, const char* Name) const { - unsigned Flags = ELFTargetAsmInfo::SectionFlagsForGlobal(GV, Name); - // Mask out Small Section flag bit, Mips doesnt support 's' section symbol - // for its small sections. - return (Flags & (~SectionFlags::Small)); -} - -SectionKind::Kind MipsTargetAsmInfo:: -SectionKindForGlobal(const GlobalValue *GV) const { - SectionKind::Kind K = ELFTargetAsmInfo::SectionKindForGlobal(GV); - - if (Subtarget->hasABICall()) - return K; - - if (K != SectionKind::Data && K != SectionKind::BSS && - K != SectionKind::RODataMergeConst) - return K; - - if (isa<GlobalVariable>(GV)) { - const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType()); - unsigned Threshold = Subtarget->getSSectionThreshold(); - - if (Size > 0 && Size <= Threshold) { - if (K == SectionKind::BSS) - return SectionKind::SmallBSS; - else - return SectionKind::SmallData; - } - } - - return K; -} - -const Section* MipsTargetAsmInfo:: -SelectSectionForGlobal(const GlobalValue *GV) const { - SectionKind::Kind K = SectionKindForGlobal(GV); - const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); - - if (GVA && (!GVA->isWeakForLinker())) - switch (K) { - case SectionKind::SmallData: - return getSmallDataSection(); - case SectionKind::SmallBSS: - return getSmallBSSSection(); - default: break; - } - - return ELFTargetAsmInfo::SelectSectionForGlobal(GV); -} diff --git a/lib/Target/Mips/MipsTargetAsmInfo.h b/lib/Target/Mips/MipsTargetAsmInfo.h deleted file mode 100644 index 2b5a739..0000000 --- a/lib/Target/Mips/MipsTargetAsmInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -//=====-- MipsTargetAsmInfo.h - Mips asm properties -----------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the MipsTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef MIPSTARGETASMINFO_H -#define MIPSTARGETASMINFO_H - -#include "MipsSubtarget.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/ELFTargetAsmInfo.h" - -namespace llvm { - - // Forward declaration. - class GlobalValue; - class MipsTargetMachine; - - struct MipsTargetAsmInfo : public ELFTargetAsmInfo { - explicit MipsTargetAsmInfo(const MipsTargetMachine &TM); - - /// SectionKindForGlobal - This hook allows the target to select proper - /// section kind used for global emission. - virtual SectionKind::Kind - SectionKindForGlobal(const GlobalValue *GV) const; - - /// SectionFlagsForGlobal - This hook allows the target to select proper - /// section flags either for given global or for section. - virtual unsigned - SectionFlagsForGlobal(const GlobalValue *GV = NULL, - const char* name = NULL) const; - - virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; - - private: - const MipsSubtarget *Subtarget; - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp deleted file mode 100644 index 1fc1cc1..0000000 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ /dev/null @@ -1,442 +0,0 @@ -//===-- PIC16AsmPrinter.cpp - PIC16 LLVM assembly writer ------------------===// -// -// 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 PIC16 assembly language. -// -//===----------------------------------------------------------------------===// - -#include "PIC16AsmPrinter.h" -#include "PIC16TargetAsmInfo.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Mangler.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" - -using namespace llvm; - -#include "PIC16GenAsmWriter.inc" - -bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { - printInstruction(MI); - return true; -} - -/// runOnMachineFunction - This emits the frame section, autos section and -/// assembly for each instruction. Also takes care of function begin debug -/// directive and file begin debug directive (if required) for the function. -/// -bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { - this->MF = &MF; - - // This calls the base class function required to be called at beginning - // of runOnMachineFunction. - SetupMachineFunction(MF); - - // Get the mangled name. - const Function *F = MF.getFunction(); - CurrentFnName = Mang->getValueName(F); - - // Emit the function frame (args and temps). - EmitFunctionFrame(MF); - - DbgInfo.BeginFunction(MF); - - // Emit the autos section of function. - EmitAutos(CurrentFnName); - - // Now emit the instructions of function in its code section. - const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str(); - - const Section *fCodeSection = TAI->getNamedSection(codeSection, - SectionFlags::Code); - // Start the Code Section. - O << "\n"; - SwitchToSection (fCodeSection); - - // Emit the frame address of the function at the beginning of code. - O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; - O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n"; - - // Emit function start label. - O << CurrentFnName << ":\n"; - - DebugLoc CurDL; - O << "\n"; - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - - // Print a label for the basic block. - if (I != MF.begin()) { - printBasicBlockLabel(I, true); - O << '\n'; - } - - // Print a basic block. - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - - // Emit the line directive if source line changed. - const DebugLoc DL = II->getDebugLoc(); - if (!DL.isUnknown() && DL != CurDL) { - DbgInfo.ChangeDebugLoc(MF, DL); - CurDL = DL; - } - - // Print the assembly for the instruction. - printMachineInstruction(II); - } - } - - // Emit function end debug directives. - DbgInfo.EndFunction(MF); - - return false; // we didn't modify anything. -} - -/// createPIC16CodePrinterPass - Returns a pass that prints the PIC16 -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createPIC16CodePrinterPass(raw_ostream &o, - PIC16TargetMachine &tm, - bool verbose) { - return new PIC16AsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); -} - - -// printOperand - print operand of insn. -void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { - const MachineOperand &MO = MI->getOperand(opNum); - - switch (MO.getType()) { - case MachineOperand::MO_Register: - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) - O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; - else - assert(0 && "not implemented"); - return; - - case MachineOperand::MO_Immediate: - O << (int)MO.getImm(); - return; - - case MachineOperand::MO_GlobalAddress: { - O << Mang->getValueName(MO.getGlobal()); - break; - } - case MachineOperand::MO_ExternalSymbol: { - const char *Sname = MO.getSymbolName(); - - // If its a libcall name, record it to decls section. - if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) { - LibcallDecls.push_back(Sname); - } - - O << Sname; - break; - } - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; - - default: - assert(0 && " Operand type not supported."); - } -} - -/// printCCOperand - Print the cond code operand. -/// -void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { - int CC = (int)MI->getOperand(opNum).getImm(); - O << PIC16CondCodeToString((PIC16CC::CondCodes)CC); -} - -/// printLibcallDecls - print the extern declarations for compiler -/// intrinsics. -/// -void PIC16AsmPrinter::printLibcallDecls(void) { - // If no libcalls used, return. - if (LibcallDecls.empty()) return; - - O << TAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n"; - // Remove duplicate entries. - LibcallDecls.sort(); - LibcallDecls.unique(); - for (std::list<const char*>::const_iterator I = LibcallDecls.begin(); - I != LibcallDecls.end(); I++) { - O << TAI->getExternDirective() << *I << "\n"; - O << TAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n"; - O << TAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n"; - } - O << TAI->getCommentString() << "External decls for libcalls - END." <<"\n"; -} - -/// doInitialization - Perfrom Module level initializations here. -/// One task that we do here is to sectionize all global variables. -/// The MemSelOptimizer pass depends on the sectionizing. -/// -bool PIC16AsmPrinter::doInitialization (Module &M) { - bool Result = AsmPrinter::doInitialization(M); - - // FIXME:: This is temporary solution to generate the include file. - // The processor should be passed to llc as in input and the header file - // should be generated accordingly. - O << "\n\t#include P16F1937.INC\n"; - - // Set the section names for all globals. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - I->setSection(TAI->SectionForGlobal(I)->getName()); - } - - DbgInfo.BeginModule(M); - EmitFunctionDecls(M); - EmitUndefinedVars(M); - EmitDefinedVars(M); - EmitIData(M); - EmitUData(M); - EmitRomData(M); - return Result; -} - -/// Emit extern decls for functions imported from other modules, and emit -/// global declarations for function defined in this module and which are -/// available to other modules. -/// -void PIC16AsmPrinter::EmitFunctionDecls (Module &M) { - // Emit declarations for external functions. - O <<"\n"<<TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; - for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { - std::string Name = Mang->getValueName(I); - if (Name.compare("@abort") == 0) - continue; - - // If it is llvm intrinsic call then don't emit - if (Name.find("llvm.") != std::string::npos) - continue; - - if (! (I->isDeclaration() || I->hasExternalLinkage())) - continue; - - const char *directive = I->isDeclaration() ? TAI->getExternDirective() : - TAI->getGlobalDirective(); - - O << directive << Name << "\n"; - O << directive << PAN::getRetvalLabel(Name) << "\n"; - O << directive << PAN::getArgsLabel(Name) << "\n"; - } - - O << TAI->getCommentString() << "Function Declarations - END." <<"\n"; -} - -// Emit variables imported from other Modules. -void PIC16AsmPrinter::EmitUndefinedVars (Module &M) -{ - std::vector<const GlobalVariable*> Items = PTAI->ExternalVarDecls->Items; - if (! Items.size()) return; - - O << "\n" << TAI->getCommentString() << "Imported Variables - BEGIN" << "\n"; - for (unsigned j = 0; j < Items.size(); j++) { - O << TAI->getExternDirective() << Mang->getValueName(Items[j]) << "\n"; - } - O << TAI->getCommentString() << "Imported Variables - END" << "\n"; -} - -// Emit variables defined in this module and are available to other modules. -void PIC16AsmPrinter::EmitDefinedVars (Module &M) -{ - std::vector<const GlobalVariable*> Items = PTAI->ExternalVarDefs->Items; - if (! Items.size()) return; - - O << "\n" << TAI->getCommentString() << "Exported Variables - BEGIN" << "\n"; - for (unsigned j = 0; j < Items.size(); j++) { - O << TAI->getGlobalDirective() << Mang->getValueName(Items[j]) << "\n"; - } - O << TAI->getCommentString() << "Exported Variables - END" << "\n"; -} - -// Emit initialized data placed in ROM. -void PIC16AsmPrinter::EmitRomData (Module &M) -{ - - std::vector<const GlobalVariable*> Items = PTAI->ROSection->Items; - if (! Items.size()) return; - - // Print ROData ection. - O << "\n"; - SwitchToSection(PTAI->ROSection->S_); - for (unsigned j = 0; j < Items.size(); j++) { - O << Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - int AddrSpace = Items[j]->getType()->getAddressSpace(); - EmitGlobalConstant(C, AddrSpace); - } -} - -bool PIC16AsmPrinter::doFinalization(Module &M) { - printLibcallDecls(); - EmitRemainingAutos(); - DbgInfo.EndModule(M); - O << "\n\t" << "END\n"; - bool Result = AsmPrinter::doFinalization(M); - return Result; -} - -void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) { - const Function *F = MF.getFunction(); - std::string FuncName = Mang->getValueName(F); - const TargetData *TD = TM.getTargetData(); - // Emit the data section name. - O << "\n"; - const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str(); - - const Section *fPDataSection = TAI->getNamedSection(SectionName, - SectionFlags::Writeable); - SwitchToSection(fPDataSection); - - // Emit function frame label - O << PAN::getFrameLabel(CurrentFnName) << ":\n"; - - const Type *RetType = F->getReturnType(); - unsigned RetSize = 0; - if (RetType->getTypeID() != Type::VoidTyID) - RetSize = TD->getTypeAllocSize(RetType); - - //Emit function return value space - // FIXME: Do not emit RetvalLable when retsize is zero. To do this - // we will need to avoid printing a global directive for Retval label - // in emitExternandGloblas. - if(RetSize > 0) - O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n"; - else - O << PAN::getRetvalLabel(CurrentFnName) << ": \n"; - - // Emit variable to hold the space for function arguments - unsigned ArgSize = 0; - for (Function::const_arg_iterator argi = F->arg_begin(), - arge = F->arg_end(); argi != arge ; ++argi) { - const Type *Ty = argi->getType(); - ArgSize += TD->getTypeAllocSize(Ty); - } - - O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n"; - - // Emit temporary space - int TempSize = PTLI->GetTmpSize(); - if (TempSize > 0 ) - O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize <<"\n"; -} - -void PIC16AsmPrinter::EmitIData (Module &M) { - - // Print all IDATA sections. - std::vector <PIC16Section *>IDATASections = PTAI->IDATASections; - for (unsigned i = 0; i < IDATASections.size(); i++) { - O << "\n"; - SwitchToSection(IDATASections[i]->S_); - std::vector<const GlobalVariable*> Items = IDATASections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string Name = Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - int AddrSpace = Items[j]->getType()->getAddressSpace(); - O << Name; - EmitGlobalConstant(C, AddrSpace); - } - } -} - -void PIC16AsmPrinter::EmitUData (Module &M) { - const TargetData *TD = TM.getTargetData(); - - // Print all BSS sections. - std::vector <PIC16Section *>BSSSections = PTAI->BSSSections; - for (unsigned i = 0; i < BSSSections.size(); i++) { - O << "\n"; - SwitchToSection(BSSSections[i]->S_); - std::vector<const GlobalVariable*> Items = BSSSections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string Name = Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD->getTypeAllocSize(Ty); - - O << Name << " " <<"RES"<< " " << Size ; - O << "\n"; - } - } -} - -void PIC16AsmPrinter::EmitAutos (std::string FunctName) -{ - // Section names for all globals are already set. - - const TargetData *TD = TM.getTargetData(); - - // Now print Autos section for this function. - std::string SectionName = PAN::getAutosSectionName(FunctName); - std::vector <PIC16Section *>AutosSections = PTAI->AutosSections; - for (unsigned i = 0; i < AutosSections.size(); i++) { - O << "\n"; - if (AutosSections[i]->S_->getName() == SectionName) { - // Set the printing status to true - AutosSections[i]->setPrintedStatus(true); - SwitchToSection(AutosSections[i]->S_); - std::vector<const GlobalVariable*> Items = AutosSections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string VarName = Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD->getTypeAllocSize(Ty); - // Emit memory reserve directive. - O << VarName << " RES " << Size << "\n"; - } - break; - } - } -} - -// Print autos that were not printed during the code printing of functions. -// As the functions might themselves would have got deleted by the optimizer. -void PIC16AsmPrinter::EmitRemainingAutos() -{ - const TargetData *TD = TM.getTargetData(); - - // Now print Autos section for this function. - std::vector <PIC16Section *>AutosSections = PTAI->AutosSections; - for (unsigned i = 0; i < AutosSections.size(); i++) { - - // if the section is already printed then don't print again - if (AutosSections[i]->isPrinted()) - continue; - - // Set status as printed - AutosSections[i]->setPrintedStatus(true); - - O << "\n"; - SwitchToSection(AutosSections[i]->S_); - std::vector<const GlobalVariable*> Items = AutosSections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string VarName = Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD->getTypeAllocSize(Ty); - // Emit memory reserve directive. - O << VarName << " RES " << Size << "\n"; - } - } -} - diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h deleted file mode 100644 index cb11687..0000000 --- a/lib/Target/PIC16/PIC16AsmPrinter.h +++ /dev/null @@ -1,70 +0,0 @@ -//===-- PIC16AsmPrinter.h - PIC16 LLVM assembly writer ------------------===// -// -// 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 PIC16 assembly language. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16ASMPRINTER_H -#define PIC16ASMPRINTER_H - -#include "PIC16.h" -#include "PIC16TargetMachine.h" -#include "PIC16DebugInfo.h" -#include "llvm/Analysis/DebugInfo.h" -#include "PIC16TargetAsmInfo.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetMachine.h" -#include <list> -#include <string> - -namespace llvm { - struct VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter { - explicit PIC16AsmPrinter(raw_ostream &O, PIC16TargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V), DbgInfo(O, T) { - PTLI = TM.getTargetLowering(); - PTAI = static_cast<const PIC16TargetAsmInfo *> (T); - } - private : - virtual const char *getPassName() const { - return "PIC16 Assembly Printer"; - } - - bool runOnMachineFunction(MachineFunction &F); - void printOperand(const MachineInstr *MI, int opNum); - void printCCOperand(const MachineInstr *MI, int opNum); - bool printInstruction(const MachineInstr *MI); // definition autogenerated. - bool printMachineInstruction(const MachineInstr *MI); - void EmitFunctionDecls (Module &M); - void EmitUndefinedVars (Module &M); - void EmitDefinedVars (Module &M); - void EmitIData (Module &M); - void EmitUData (Module &M); - void EmitAutos (std::string FunctName); - void EmitRemainingAutos (); - void EmitRomData (Module &M); - void EmitFunctionFrame(MachineFunction &MF); - void printLibcallDecls(void); - protected: - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - private: - PIC16TargetLowering *PTLI; - PIC16DbgInfo DbgInfo; - const PIC16TargetAsmInfo *PTAI; - std::list<const char *> LibcallDecls; // List of extern decls. - }; -} // end of namespace - -#endif diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp deleted file mode 100644 index d2657f0..0000000 --- a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp +++ /dev/null @@ -1,264 +0,0 @@ -//===-- PIC16TargetAsmInfo.cpp - PIC16 asm properties ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the PIC16TargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "PIC16TargetAsmInfo.h" -#include "PIC16TargetMachine.h" -#include "llvm/GlobalValue.h" -#include "llvm/GlobalVariable.h" -#include "llvm/DerivedTypes.h" - -using namespace llvm; - -PIC16TargetAsmInfo:: -PIC16TargetAsmInfo(const PIC16TargetMachine &TM) - : TargetAsmInfo(TM) { - CommentString = ";"; - GlobalPrefix = PAN::getTagName(PAN::PREFIX_SYMBOL); - GlobalDirective = "\tglobal\t"; - ExternDirective = "\textern\t"; - - Data8bitsDirective = " db "; - Data16bitsDirective = " dw "; - Data32bitsDirective = " dl "; - RomData8bitsDirective = " dw "; - RomData16bitsDirective = " rom_di "; - RomData32bitsDirective = " rom_dl "; - ZeroDirective = NULL; - AsciiDirective = " dt "; - AscizDirective = NULL; - BSSSection_ = getNamedSection("udata.# UDATA", - SectionFlags::Writeable | SectionFlags::BSS); - ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None); - DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable); - SwitchToSectionDirective = ""; - // Need because otherwise a .text symbol is emitted by DwarfWriter - // in BeginModule, and gpasm cribbs for that .text symbol. - TextSection = getUnnamedSection("", SectionFlags::Code); - ROSection = new PIC16Section(getReadOnlySection()); - ExternalVarDecls = new PIC16Section(getNamedSection("ExternalVarDecls")); - ExternalVarDefs = new PIC16Section(getNamedSection("ExternalVarDefs")); - // Set it to false because we weed to generate c file name and not bc file - // name. - HasSingleParameterDotFile = false; -} - -const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const -{ - if (size == 8) - return RomData8bitsDirective; - else if (size == 16) - return RomData16bitsDirective; - else if (size == 32) - return RomData32bitsDirective; - else - return NULL; -} - - -const char *PIC16TargetAsmInfo::getASDirective(unsigned size, - unsigned AS) const { - if (AS == PIC16ISD::ROM_SPACE) - return getRomDirective(size); - else - return NULL; -} - -const Section * -PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const { - assert (GV->hasInitializer() && "This global doesn't need space"); - Constant *C = GV->getInitializer(); - assert (C->isNullValue() && "Unitialized globals has non-zero initializer"); - - // Find how much space this global needs. - const TargetData *TD = TM.getTargetData(); - const Type *Ty = C->getType(); - unsigned ValSize = TD->getTypeAllocSize(Ty); - - // Go through all BSS Sections and assign this variable - // to the first available section having enough space. - PIC16Section *FoundBSS = NULL; - for (unsigned i = 0; i < BSSSections.size(); i++) { - if (DataBankSize - BSSSections[i]->Size >= ValSize) { - FoundBSS = BSSSections[i]; - break; - } - } - - // No BSS section spacious enough was found. Crate a new one. - if (! FoundBSS) { - std::string name = PAN::getUdataSectionName(BSSSections.size()); - const Section *NewSection = getNamedSection (name.c_str()); - - FoundBSS = new PIC16Section(NewSection); - - // Add this newly created BSS section to the list of BSSSections. - BSSSections.push_back(FoundBSS); - } - - // Insert the GV into this BSS. - FoundBSS->Items.push_back(GV); - FoundBSS->Size += ValSize; - - // We can't do this here because GV is const . - // const std::string SName = FoundBSS->S_->getName(); - // GV->setSection(SName); - - return FoundBSS->S_; -} - -const Section * -PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const { - assert (GV->hasInitializer() && "This global doesn't need space"); - Constant *C = GV->getInitializer(); - assert (!C->isNullValue() && "initialized globals has zero initializer"); - assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE && - "can split initialized RAM data only"); - - // Find how much space this global needs. - const TargetData *TD = TM.getTargetData(); - const Type *Ty = C->getType(); - unsigned ValSize = TD->getTypeAllocSize(Ty); - - // Go through all IDATA Sections and assign this variable - // to the first available section having enough space. - PIC16Section *FoundIDATA = NULL; - for (unsigned i = 0; i < IDATASections.size(); i++) { - if ( DataBankSize - IDATASections[i]->Size >= ValSize) { - FoundIDATA = IDATASections[i]; - break; - } - } - - // No IDATA section spacious enough was found. Crate a new one. - if (! FoundIDATA) { - std::string name = PAN::getIdataSectionName(IDATASections.size()); - const Section *NewSection = getNamedSection (name.c_str()); - - FoundIDATA = new PIC16Section(NewSection); - - // Add this newly created IDATA section to the list of IDATASections. - IDATASections.push_back(FoundIDATA); - } - - // Insert the GV into this IDATA. - FoundIDATA->Items.push_back(GV); - FoundIDATA->Size += ValSize; - - // We can't do this here because GV is const . - // GV->setSection(FoundIDATA->S->getName()); - - return FoundIDATA->S_; -} - -// Get the section for an automatic variable of a function. -// For PIC16 they are globals only with mangled names. -const Section * -PIC16TargetAsmInfo::getSectionForAuto(const GlobalVariable *GV) const { - - const std::string name = PAN::getSectionNameForSym(GV->getName()); - - // Go through all Auto Sections and assign this variable - // to the appropriate section. - PIC16Section *FoundAutoSec = NULL; - for (unsigned i = 0; i < AutosSections.size(); i++) { - if ( AutosSections[i]->S_->getName() == name) { - FoundAutoSec = AutosSections[i]; - break; - } - } - - // No Auto section was found. Crate a new one. - if (! FoundAutoSec) { - const Section *NewSection = getNamedSection (name.c_str()); - - FoundAutoSec = new PIC16Section(NewSection); - - // Add this newly created autos section to the list of AutosSections. - AutosSections.push_back(FoundAutoSec); - } - - // Insert the auto into this section. - FoundAutoSec->Items.push_back(GV); - - return FoundAutoSec->S_; -} - - -// Override default implementation to put the true globals into -// multiple data sections if required. -const Section* -PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { - // We select the section based on the initializer here, so it really - // has to be a GlobalVariable. - const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); - - if (!GV) - return TargetAsmInfo::SelectSectionForGlobal(GV1); - - // Record Exteranl Var Decls. - if (GV->isDeclaration()) { - ExternalVarDecls->Items.push_back(GV); - return ExternalVarDecls->S_; - } - - assert (GV->hasInitializer() && "A def without initializer?"); - - // First, if this is an automatic variable for a function, get the section - // name for it and return. - const std::string name = GV->getName(); - if (PAN::isLocalName(name)) { - return getSectionForAuto(GV); - } - - // Record Exteranl Var Defs. - if (GV->hasExternalLinkage() || GV->hasCommonLinkage()) { - ExternalVarDefs->Items.push_back(GV); - } - - // See if this is an uninitialized global. - const Constant *C = GV->getInitializer(); - if (C->isNullValue()) - return getBSSSectionForGlobal(GV); - - // If this is initialized data in RAM. Put it in the correct IDATA section. - if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - return getIDATASectionForGlobal(GV); - - // This is initialized data in rom, put it in the readonly section. - if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) { - ROSection->Items.push_back(GV); - return ROSection->S_; - } - - // Else let the default implementation take care of it. - return TargetAsmInfo::SelectSectionForGlobal(GV); -} - -PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { - - for (unsigned i = 0; i < BSSSections.size(); i++) { - delete BSSSections[i]; - } - - for (unsigned i = 0; i < IDATASections.size(); i++) { - delete IDATASections[i]; - } - - for (unsigned i = 0; i < AutosSections.size(); i++) { - delete AutosSections[i]; - } - - delete ROSection; - delete ExternalVarDecls; - delete ExternalVarDefs; -} diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.h b/lib/Target/PIC16/PIC16TargetAsmInfo.h deleted file mode 100644 index b7292b8..0000000 --- a/lib/Target/PIC16/PIC16TargetAsmInfo.h +++ /dev/null @@ -1,83 +0,0 @@ -//=====-- PIC16TargetAsmInfo.h - PIC16 asm properties ---------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the PIC16TargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef PIC16TARGETASMINFO_H -#define PIC16TARGETASMINFO_H - -#include "PIC16.h" -#include "llvm/Target/TargetAsmInfo.h" -#include <vector> -#include "llvm/Module.h" -#define DataBankSize 80 -namespace llvm { - - // Forward declaration. - class PIC16TargetMachine; - class GlobalVariable; - - // PIC16 Splits the global data into mulitple udata and idata sections. - // Each udata and idata section needs to contain a list of globals that - // they contain, in order to avoid scanning over all the global values - // again and printing only those that match the current section. - // Keeping values inside the sections make printing a section much easier. - struct PIC16Section { - const Section *S_; // Connection to actual Section. - unsigned Size; // Total size of the objects contained. - bool SectionPrinted; - std::vector<const GlobalVariable*> Items; - - PIC16Section (const Section *s) { S_ = s; Size = 0; - SectionPrinted = false;} - bool isPrinted() { return SectionPrinted ; } - void setPrintedStatus(bool status) { SectionPrinted = status ;} - }; - - struct PIC16TargetAsmInfo : public TargetAsmInfo { - std::string getSectionNameForSym(const std::string &Sym) const; - PIC16TargetAsmInfo(const PIC16TargetMachine &TM); - mutable std::vector<PIC16Section *> BSSSections; - mutable std::vector<PIC16Section *> IDATASections; - mutable std::vector<PIC16Section *> AutosSections; - mutable PIC16Section *ROSection; - mutable PIC16Section *ExternalVarDecls; - mutable PIC16Section *ExternalVarDefs; - virtual ~PIC16TargetAsmInfo(); - - private: - const char *RomData8bitsDirective; - const char *RomData16bitsDirective; - const char *RomData32bitsDirective; - const char *getRomDirective(unsigned size) const; - virtual const char *getASDirective(unsigned size, unsigned AS) const; - const Section *getBSSSectionForGlobal(const GlobalVariable *GV) const; - const Section *getIDATASectionForGlobal(const GlobalVariable *GV) const; - const Section *getSectionForAuto(const GlobalVariable *GV) const; - virtual const Section *SelectSectionForGlobal(const GlobalValue *GV) const; - - - public: - void SetSectionForGVs(Module &M); - std::vector<PIC16Section *> getBSSSections() const { - return BSSSections; - } - std::vector<PIC16Section *> getIDATASections() const { - return IDATASections; - } - std::vector<PIC16Section *> getAutosSections() const { - return AutosSections; - } - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp deleted file mode 100644 index ebffd69..0000000 --- a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//===-- PPCTargetAsmInfo.cpp - PPC asm properties ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the DarwinTargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "PPCTargetAsmInfo.h" -#include "PPCTargetMachine.h" -#include "llvm/Function.h" -#include "llvm/Support/Dwarf.h" - -using namespace llvm; -using namespace llvm::dwarf; - -PPCDarwinTargetAsmInfo::PPCDarwinTargetAsmInfo(const PPCTargetMachine &TM) : - PPCTargetAsmInfo<DarwinTargetAsmInfo>(TM) { - PCSymbol = "."; - CommentString = ";"; - ConstantPoolSection = "\t.const\t"; - UsedDirective = "\t.no_dead_strip\t"; - SupportsExceptionHandling = true; - - DwarfEHFrameSection = - ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; - DwarfExceptionSection = ".section __DATA,__gcc_except_tab"; - GlobalEHDirective = "\t.globl\t"; - SupportsWeakOmittedEHFrame = false; -} - -/// PreferredEHDataFormat - This hook allows the target to select data -/// format used for encoding pointers in exception handling data. Reason is -/// 0 for data, 1 for code labels, 2 for function pointers. Global is true -/// if the symbol can be relocated. -unsigned -PPCDarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - if (Reason == DwarfEncoding::Functions && Global) - return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); - else if (Reason == DwarfEncoding::CodeLabels || !Global) - return DW_EH_PE_pcrel; - else - return DW_EH_PE_absptr; -} - -const char * -PPCDarwinTargetAsmInfo::getEHGlobalPrefix() const -{ - const PPCSubtarget* Subtarget = &TM.getSubtarget<PPCSubtarget>(); - if (Subtarget->getDarwinVers() > 9) - return PrivateGlobalPrefix; - else - return ""; -} - -PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) : - PPCTargetAsmInfo<ELFTargetAsmInfo>(TM) { - CommentString = "#"; - GlobalPrefix = ""; - PrivateGlobalPrefix = ".L"; - ConstantPoolSection = "\t.section .rodata.cst4\t"; - JumpTableDataSection = ".section .rodata.cst4"; - CStringSection = ".rodata.str"; - StaticCtorsSection = ".section\t.ctors,\"aw\",@progbits"; - StaticDtorsSection = ".section\t.dtors,\"aw\",@progbits"; - UsedDirective = "\t# .no_dead_strip\t"; - WeakRefDirective = "\t.weak\t"; - BSSSection = "\t.section\t\".sbss\",\"aw\",@nobits"; - - // PPC/Linux normally uses named section for BSS. - BSSSection_ = getNamedSection("\t.bss", - SectionFlags::Writeable | SectionFlags::BSS, - /* Override */ true); - - // Debug Information - AbsoluteDebugSectionOffsets = true; - SupportsDebugInformation = true; - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits"; - DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits"; - DwarfLineSection = "\t.section\t.debug_line,\"\",@progbits"; - DwarfFrameSection = "\t.section\t.debug_frame,\"\",@progbits"; - DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits"; - DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits"; - DwarfStrSection = "\t.section\t.debug_str,\"\",@progbits"; - DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; - DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; - DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; - - PCSymbol = "."; - - // Set up DWARF directives - HasLEB128 = true; // Target asm supports leb128 directives (little-endian) - - // Exceptions handling - if (!TM.getSubtargetImpl()->isPPC64()) - SupportsExceptionHandling = true; - AbsoluteEHSectionOffsets = false; - DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits"; - DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits"; -} - -/// PreferredEHDataFormat - This hook allows the target to select data -/// format used for encoding pointers in exception handling data. Reason is -/// 0 for data, 1 for code labels, 2 for function pointers. Global is true -/// if the symbol can be relocated. -unsigned -PPCLinuxTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - // We really need to write something here. - return TargetAsmInfo::PreferredEHDataFormat(Reason, Global); -} - -// Instantiate default implementation. -TEMPLATE_INSTANTIATION(class PPCTargetAsmInfo<TargetAsmInfo>); diff --git a/lib/Target/PowerPC/PPCTargetAsmInfo.h b/lib/Target/PowerPC/PPCTargetAsmInfo.h deleted file mode 100644 index edf40c9..0000000 --- a/lib/Target/PowerPC/PPCTargetAsmInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -//=====-- PPCTargetAsmInfo.h - PPC asm properties -------------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the DarwinTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef PPCTARGETASMINFO_H -#define PPCTARGETASMINFO_H - -#include "PPCTargetMachine.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/DarwinTargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - - template <class BaseTAI> - struct PPCTargetAsmInfo : public BaseTAI { - explicit PPCTargetAsmInfo(const PPCTargetMachine &TM): - BaseTAI(TM) { - const PPCSubtarget *Subtarget = &TM.getSubtarget<PPCSubtarget>(); - bool isPPC64 = Subtarget->isPPC64(); - - BaseTAI::ZeroDirective = "\t.space\t"; - BaseTAI::SetDirective = "\t.set"; - BaseTAI::Data64bitsDirective = isPPC64 ? "\t.quad\t" : 0; - BaseTAI::AlignmentIsInBytes = false; - BaseTAI::LCOMMDirective = "\t.lcomm\t"; - BaseTAI::InlineAsmStart = "# InlineAsm Start"; - BaseTAI::InlineAsmEnd = "# InlineAsm End"; - BaseTAI::AssemblerDialect = Subtarget->getAsmFlavor(); - } - }; - - typedef PPCTargetAsmInfo<TargetAsmInfo> PPCGenericTargetAsmInfo; - - EXTERN_TEMPLATE_INSTANTIATION(class PPCTargetAsmInfo<TargetAsmInfo>); - - struct PPCDarwinTargetAsmInfo : public PPCTargetAsmInfo<DarwinTargetAsmInfo> { - explicit PPCDarwinTargetAsmInfo(const PPCTargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - virtual const char *getEHGlobalPrefix() const; - }; - - struct PPCLinuxTargetAsmInfo : public PPCTargetAsmInfo<ELFTargetAsmInfo> { - explicit PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/Sparc/SparcTargetAsmInfo.cpp b/lib/Target/Sparc/SparcTargetAsmInfo.cpp deleted file mode 100644 index c13d45c..0000000 --- a/lib/Target/Sparc/SparcTargetAsmInfo.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===-- SparcTargetAsmInfo.cpp - Sparc asm properties -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the SparcTargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "SparcTargetAsmInfo.h" - -using namespace llvm; - -SparcELFTargetAsmInfo::SparcELFTargetAsmInfo(const TargetMachine &TM): - ELFTargetAsmInfo(TM) { - Data16bitsDirective = "\t.half\t"; - Data32bitsDirective = "\t.word\t"; - Data64bitsDirective = 0; // .xword is only supported by V9. - ZeroDirective = "\t.skip\t"; - CommentString = "!"; - ConstantPoolSection = "\t.section \".rodata\",#alloc\n"; - COMMDirectiveTakesAlignment = true; - CStringSection=".rodata.str"; - - // Sparc normally uses named section for BSS. - BSSSection_ = getNamedSection("\t.bss", - SectionFlags::Writeable | SectionFlags::BSS, - /* Override */ true); -} - -std::string SparcELFTargetAsmInfo::printSectionFlags(unsigned flags) const { - if (flags & SectionFlags::Mergeable) - return ELFTargetAsmInfo::printSectionFlags(flags); - - std::string Flags; - if (!(flags & SectionFlags::Debug)) - Flags += ",#alloc"; - if (flags & SectionFlags::Code) - Flags += ",#execinstr"; - if (flags & SectionFlags::Writeable) - Flags += ",#write"; - if (flags & SectionFlags::TLS) - Flags += ",#tls"; - - return Flags; -} diff --git a/lib/Target/Sparc/SparcTargetAsmInfo.h b/lib/Target/Sparc/SparcTargetAsmInfo.h deleted file mode 100644 index 1af5d80..0000000 --- a/lib/Target/Sparc/SparcTargetAsmInfo.h +++ /dev/null @@ -1,33 +0,0 @@ -//=====-- SparcTargetAsmInfo.h - Sparc asm properties ---------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the SparcTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef SPARCTARGETASMINFO_H -#define SPARCTARGETASMINFO_H - -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" - -namespace llvm { - - // Forward declaration. - class TargetMachine; - - struct SparcELFTargetAsmInfo : public ELFTargetAsmInfo { - explicit SparcELFTargetAsmInfo(const TargetMachine &TM); - - std::string printSectionFlags(unsigned flags) const; - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp deleted file mode 100644 index 3f5f1bd..0000000 --- a/lib/Target/TargetAsmInfo.cpp +++ /dev/null @@ -1,456 +0,0 @@ -//===-- TargetAsmInfo.cpp - Asm Info ---------------------------------------==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines target asm properties related what form asm statements -// should take. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Function.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Support/Dwarf.h" -#include <cctype> -#include <cstring> -using namespace llvm; - -TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) -: TM(tm) { - BSSSection = "\t.bss"; - BSSSection_ = 0; - ReadOnlySection = 0; - SmallDataSection = 0; - SmallBSSSection = 0; - SmallRODataSection = 0; - TLSDataSection = 0; - TLSBSSSection = 0; - ZeroFillDirective = 0; - NonexecutableStackDirective = 0; - NeedsSet = false; - MaxInstLength = 4; - PCSymbol = "$"; - SeparatorChar = ';'; - CommentString = "#"; - GlobalPrefix = ""; - PrivateGlobalPrefix = "."; - LessPrivateGlobalPrefix = ""; - JumpTableSpecialLabelPrefix = 0; - GlobalVarAddrPrefix = ""; - GlobalVarAddrSuffix = ""; - FunctionAddrPrefix = ""; - FunctionAddrSuffix = ""; - PersonalityPrefix = ""; - PersonalitySuffix = ""; - NeedsIndirectEncoding = false; - InlineAsmStart = "#APP"; - InlineAsmEnd = "#NO_APP"; - AssemblerDialect = 0; - StringConstantPrefix = ".str"; - AllowQuotesInName = false; - ZeroDirective = "\t.zero\t"; - ZeroDirectiveSuffix = 0; - AsciiDirective = "\t.ascii\t"; - AscizDirective = "\t.asciz\t"; - Data8bitsDirective = "\t.byte\t"; - Data16bitsDirective = "\t.short\t"; - Data32bitsDirective = "\t.long\t"; - Data64bitsDirective = "\t.quad\t"; - AlignDirective = "\t.align\t"; - AlignmentIsInBytes = true; - TextAlignFillValue = 0; - SwitchToSectionDirective = "\t.section\t"; - TextSectionStartSuffix = ""; - DataSectionStartSuffix = ""; - SectionEndDirectiveSuffix = 0; - ConstantPoolSection = "\t.section .rodata"; - JumpTableDataSection = "\t.section .rodata"; - JumpTableDirective = 0; - CStringSection = 0; - CStringSection_ = 0; - // FIXME: Flags are ELFish - replace with normal section stuff. - StaticCtorsSection = "\t.section .ctors,\"aw\",@progbits"; - StaticDtorsSection = "\t.section .dtors,\"aw\",@progbits"; - GlobalDirective = "\t.globl\t"; - SetDirective = 0; - LCOMMDirective = 0; - COMMDirective = "\t.comm\t"; - COMMDirectiveTakesAlignment = true; - HasDotTypeDotSizeDirective = true; - HasSingleParameterDotFile = true; - UsedDirective = 0; - WeakRefDirective = 0; - WeakDefDirective = 0; - // FIXME: These are ELFish - move to ELFTAI. - HiddenDirective = "\t.hidden\t"; - ProtectedDirective = "\t.protected\t"; - AbsoluteDebugSectionOffsets = false; - AbsoluteEHSectionOffsets = false; - HasLEB128 = false; - HasDotLocAndDotFile = false; - SupportsDebugInformation = false; - SupportsExceptionHandling = false; - DwarfRequiresFrameSection = true; - DwarfUsesInlineInfoSection = false; - NonLocalEHFrameLabel = false; - GlobalEHDirective = 0; - SupportsWeakOmittedEHFrame = true; - DwarfSectionOffsetDirective = 0; - DwarfAbbrevSection = ".debug_abbrev"; - DwarfInfoSection = ".debug_info"; - DwarfLineSection = ".debug_line"; - DwarfFrameSection = ".debug_frame"; - DwarfPubNamesSection = ".debug_pubnames"; - DwarfPubTypesSection = ".debug_pubtypes"; - DwarfDebugInlineSection = ".debug_inlined"; - DwarfStrSection = ".debug_str"; - DwarfLocSection = ".debug_loc"; - DwarfARangesSection = ".debug_aranges"; - DwarfRangesSection = ".debug_ranges"; - DwarfMacroInfoSection = ".debug_macinfo"; - DwarfEHFrameSection = ".eh_frame"; - DwarfExceptionSection = ".gcc_except_table"; - AsmTransCBE = 0; - TextSection = getUnnamedSection("\t.text", SectionFlags::Code); - DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable); -} - -TargetAsmInfo::~TargetAsmInfo() { -} - -/// Measure the specified inline asm to determine an approximation of its -/// length. -/// Comments (which run till the next SeparatorChar or newline) do not -/// count as an instruction. -/// Any other non-whitespace text is considered an instruction, with -/// multiple instructions separated by SeparatorChar or newlines. -/// Variable-length instructions are not handled here; this function -/// may be overloaded in the target code to do that. -unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const { - // Count the number of instructions in the asm. - bool atInsnStart = true; - unsigned Length = 0; - for (; *Str; ++Str) { - if (*Str == '\n' || *Str == SeparatorChar) - atInsnStart = true; - if (atInsnStart && !isspace(*Str)) { - Length += MaxInstLength; - atInsnStart = false; - } - if (atInsnStart && strncmp(Str, CommentString, strlen(CommentString))==0) - atInsnStart = false; - } - - return Length; -} - -unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - return dwarf::DW_EH_PE_absptr; -} - -static bool isSuitableForBSS(const GlobalVariable *GV) { - if (!GV->hasInitializer()) - return true; - - // Leave constant zeros in readonly constant sections, so they can be shared - Constant *C = GV->getInitializer(); - return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS); -} - -static bool isConstantString(const Constant *C) { - // First check: is we have constant array of i8 terminated with zero - const ConstantArray *CVA = dyn_cast<ConstantArray>(C); - // Check, if initializer is a null-terminated string - if (CVA && CVA->isCString()) - return true; - - // Another possibility: [1 x i8] zeroinitializer - if (isa<ConstantAggregateZero>(C)) { - if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType())) { - return (Ty->getElementType() == Type::Int8Ty && - Ty->getNumElements() == 1); - } - } - - return false; -} - -unsigned TargetAsmInfo::RelocBehaviour() const { - // By default - all relocations in PIC mode would force symbol to be - // placed in r/w section. - return (TM.getRelocationModel() != Reloc::Static ? - Reloc::LocalOrGlobal : Reloc::None); -} - -SectionKind::Kind -TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { - // Early exit - functions should be always in text sections. - if (isa<Function>(GV)) - return SectionKind::Text; - - const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV); - bool isThreadLocal = GVar->isThreadLocal(); - assert(GVar && "Invalid global value for section selection"); - - if (isSuitableForBSS(GVar)) { - // Variable can be easily put to BSS section. - return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS); - } else if (GVar->isConstant() && !isThreadLocal) { - // Now we know, that varible has initializer and it is constant. We need to - // check its initializer to decide, which section to output it into. Also - // note, there is no thread-local r/o section. - Constant *C = GVar->getInitializer(); - if (C->ContainsRelocations(Reloc::LocalOrGlobal)) { - // Decide, whether it is still possible to put symbol into r/o section. - unsigned Reloc = RelocBehaviour(); - - // We already did a query for 'all' relocs, thus - early exits. - if (Reloc == Reloc::LocalOrGlobal) - return SectionKind::Data; - else if (Reloc == Reloc::None) - return SectionKind::ROData; - else { - // Ok, target wants something funny. Honour it. - return (C->ContainsRelocations(Reloc) ? - SectionKind::Data : SectionKind::ROData); - } - } else { - // Check, if initializer is a null-terminated string - if (isConstantString(C)) - return SectionKind::RODataMergeStr; - else - return SectionKind::RODataMergeConst; - } - } - - // Variable either is not constant or thread-local - output to data section. - return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data); -} - -unsigned -TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV, - const char* Name) const { - unsigned Flags = SectionFlags::None; - - // Decode flags from global itself. - if (GV) { - SectionKind::Kind Kind = SectionKindForGlobal(GV); - switch (Kind) { - case SectionKind::Text: - Flags |= SectionFlags::Code; - break; - case SectionKind::ThreadData: - case SectionKind::ThreadBSS: - Flags |= SectionFlags::TLS; - // FALLS THROUGH - case SectionKind::Data: - case SectionKind::DataRel: - case SectionKind::DataRelLocal: - case SectionKind::DataRelRO: - case SectionKind::DataRelROLocal: - case SectionKind::BSS: - Flags |= SectionFlags::Writeable; - break; - case SectionKind::ROData: - case SectionKind::RODataMergeStr: - case SectionKind::RODataMergeConst: - // No additional flags here - break; - case SectionKind::SmallData: - case SectionKind::SmallBSS: - Flags |= SectionFlags::Writeable; - // FALLS THROUGH - case SectionKind::SmallROData: - Flags |= SectionFlags::Small; - break; - default: - assert(0 && "Unexpected section kind!"); - } - - if (GV->isWeakForLinker()) - Flags |= SectionFlags::Linkonce; - } - - // Add flags from sections, if any. - if (Name && *Name) { - Flags |= SectionFlags::Named; - - // Some lame default implementation based on some magic section names. - if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 || - strncmp(Name, ".llvm.linkonce.b.", 17) == 0 || - strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 || - strncmp(Name, ".llvm.linkonce.sb.", 18) == 0) - Flags |= SectionFlags::BSS; - else if (strcmp(Name, ".tdata") == 0 || - strncmp(Name, ".tdata.", 7) == 0 || - strncmp(Name, ".gnu.linkonce.td.", 17) == 0 || - strncmp(Name, ".llvm.linkonce.td.", 18) == 0) - Flags |= SectionFlags::TLS; - else if (strcmp(Name, ".tbss") == 0 || - strncmp(Name, ".tbss.", 6) == 0 || - strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 || - strncmp(Name, ".llvm.linkonce.tb.", 18) == 0) - Flags |= SectionFlags::BSS | SectionFlags::TLS; - } - - return Flags; -} - -const Section* -TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { - const Section* S; - // Select section name - if (GV->hasSection()) { - // Honour section already set, if any - unsigned Flags = SectionFlagsForGlobal(GV, - GV->getSection().c_str()); - S = getNamedSection(GV->getSection().c_str(), Flags); - } else { - // Use default section depending on the 'type' of global - S = SelectSectionForGlobal(GV); - } - - return S; -} - -// Lame default implementation. Calculate the section name for global. -const Section* -TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { - SectionKind::Kind Kind = SectionKindForGlobal(GV); - - if (GV->isWeakForLinker()) { - std::string Name = UniqueSectionForGlobal(GV, Kind); - unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); - return getNamedSection(Name.c_str(), Flags); - } else { - if (Kind == SectionKind::Text) - return getTextSection(); - else if (isBSS(Kind) && getBSSSection_()) - return getBSSSection_(); - else if (getReadOnlySection() && SectionKind::isReadOnly(Kind)) - return getReadOnlySection(); - } - - return getDataSection(); -} - -// Lame default implementation. Calculate the section name for machine const. -const Section* -TargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { - // FIXME: Support data.rel stuff someday - return getDataSection(); -} - -std::string -TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, - SectionKind::Kind Kind) const { - switch (Kind) { - case SectionKind::Text: - return ".gnu.linkonce.t." + GV->getName(); - case SectionKind::Data: - return ".gnu.linkonce.d." + GV->getName(); - case SectionKind::DataRel: - return ".gnu.linkonce.d.rel" + GV->getName(); - case SectionKind::DataRelLocal: - return ".gnu.linkonce.d.rel.local" + GV->getName(); - case SectionKind::DataRelRO: - return ".gnu.linkonce.d.rel.ro" + GV->getName(); - case SectionKind::DataRelROLocal: - return ".gnu.linkonce.d.rel.ro.local" + GV->getName(); - case SectionKind::SmallData: - return ".gnu.linkonce.s." + GV->getName(); - case SectionKind::BSS: - return ".gnu.linkonce.b." + GV->getName(); - case SectionKind::SmallBSS: - return ".gnu.linkonce.sb." + GV->getName(); - case SectionKind::ROData: - case SectionKind::RODataMergeConst: - case SectionKind::RODataMergeStr: - return ".gnu.linkonce.r." + GV->getName(); - case SectionKind::SmallROData: - return ".gnu.linkonce.s2." + GV->getName(); - case SectionKind::ThreadData: - return ".gnu.linkonce.td." + GV->getName(); - case SectionKind::ThreadBSS: - return ".gnu.linkonce.tb." + GV->getName(); - default: - assert(0 && "Unknown section kind"); - } - return NULL; -} - -const Section* -TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags, - bool Override) const { - Section& S = Sections[Name]; - - // This is newly-created section, set it up properly. - if (S.Flags == SectionFlags::Invalid || Override) { - S.Flags = Flags | SectionFlags::Named; - S.Name = Name; - } - - return &S; -} - -const Section* -TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags, - bool Override) const { - Section& S = Sections[Directive]; - - // This is newly-created section, set it up properly. - if (S.Flags == SectionFlags::Invalid || Override) { - S.Flags = Flags & ~SectionFlags::Named; - S.Name = Directive; - } - - return &S; -} - -const std::string& -TargetAsmInfo::getSectionFlags(unsigned Flags) const { - SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags); - - // We didn't print these flags yet, print and save them to map. This reduces - // amount of heap trashing due to std::string construction / concatenation. - if (I == FlagsStrings.end()) - I = FlagsStrings.insert(std::make_pair(Flags, - printSectionFlags(Flags))).first; - - return I->second; -} - -unsigned TargetAsmInfo::getULEB128Size(unsigned Value) { - unsigned Size = 0; - do { - Value >>= 7; - Size += sizeof(int8_t); - } while (Value); - return Size; -} - -unsigned TargetAsmInfo::getSLEB128Size(int Value) { - unsigned Size = 0; - int Sign = Value >> (8 * sizeof(Value) - 1); - bool IsMore; - - do { - unsigned Byte = Value & 0x7f; - Value >>= 7; - IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; - Size += sizeof(int8_t); - } while (IsMore); - return Size; -} diff --git a/lib/Target/TargetMachineRegistry.cpp b/lib/Target/TargetMachineRegistry.cpp deleted file mode 100644 index c1a4777..0000000 --- a/lib/Target/TargetMachineRegistry.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//===-- TargetMachineRegistry.cpp - Target Auto Registration Impl ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file exposes the RegisterTarget class, which TargetMachine -// implementations should use to register themselves with the system. This file -// also exposes the TargetMachineRegistry class, which allows tools to inspect -// all of registered targets. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Target/TargetMachineRegistry.h" -#include <algorithm> -using namespace llvm; - -/// getClosestStaticTargetForModule - Given an LLVM module, pick the best target -/// that is compatible with the module. If no close target can be found, this -/// returns null and sets the Error string to a reason. -const TargetMachineRegistry::entry * -TargetMachineRegistry::getClosestStaticTargetForModule(const Module &M, - std::string &Error) { - std::vector<std::pair<unsigned, const entry *> > UsableTargets; - for (Registry<TargetMachine>::iterator I = begin(), E = end(); I != E; ++I) - if (unsigned Qual = I->ModuleMatchQualityFn(M)) - UsableTargets.push_back(std::make_pair(Qual, &*I)); - - if (UsableTargets.empty()) { - Error = "No available targets are compatible with this module"; - return 0; - } else if (UsableTargets.size() == 1) - return UsableTargets.back().second; - - // Otherwise, take the best target, but make sure we don't have two equally - // good best targets. - std::sort(UsableTargets.begin(), UsableTargets.end()); - if (UsableTargets.back().first ==UsableTargets[UsableTargets.size()-2].first){ - Error = "Cannot choose between targets \"" + - std::string(UsableTargets.back().second->Name) + "\" and \"" + - std::string(UsableTargets[UsableTargets.size()-2].second->Name) + "\""; - return 0; - } - return UsableTargets.back().second; -} - -/// getClosestTargetForJIT - Pick the best target that is compatible with -/// the current host. If no close target can be found, this returns null -/// and sets the Error string to a reason. -const TargetMachineRegistry::entry * -TargetMachineRegistry::getClosestTargetForJIT(std::string &Error) { - std::vector<std::pair<unsigned, const entry *> > UsableTargets; - for (Registry<TargetMachine>::iterator I = begin(), E = end(); I != E; ++I) - if (unsigned Qual = I->JITMatchQualityFn()) - UsableTargets.push_back(std::make_pair(Qual, &*I)); - - if (UsableTargets.empty()) { - Error = "No JIT is available for this host"; - return 0; - } else if (UsableTargets.size() == 1) - return UsableTargets.back().second; - - // Otherwise, take the best target. If there is a tie, just pick one. - unsigned MaxQual = UsableTargets.front().first; - const entry *MaxQualTarget = UsableTargets.front().second; - - for (unsigned i = 1, e = UsableTargets.size(); i != e; ++i) - if (UsableTargets[i].first > MaxQual) { - MaxQual = UsableTargets[i].first; - MaxQualTarget = UsableTargets[i].second; - } - - return MaxQualTarget; -} - diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp deleted file mode 100644 index 127f228..0000000 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ /dev/null @@ -1,1108 +0,0 @@ -//===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly -----===// -// -// 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 AT&T format assembly -// language. This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "X86ATTAsmPrinter.h" -#include "X86.h" -#include "X86COFF.h" -#include "X86MachineFunctionInfo.h" -#include "X86TargetMachine.h" -#include "X86TargetAsmInfo.h" -#include "llvm/CallingConv.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/MDNode.h" -#include "llvm/Type.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetOptions.h" -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -static cl::opt<bool> NewAsmPrinter("experimental-asm-printer", - cl::Hidden); - -//===----------------------------------------------------------------------===// -// Primitive Helper Functions. -//===----------------------------------------------------------------------===// - -void X86ATTAsmPrinter::PrintPICBaseSymbol() const { - if (Subtarget->isTargetDarwin()) - O << "\"L" << getFunctionNumber() << "$pb\""; - else if (Subtarget->isTargetELF()) - O << ".Lllvm$" << getFunctionNumber() << "." "$piclabel"; - else - assert(0 && "Don't know how to print PIC label!\n"); -} - -/// PrintUnmangledNameSafely - Print out the printable characters in the name. -/// Don't print things like \\n or \\0. -static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { - for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); - Name != E; ++Name) - if (isprint(*Name)) - OS << *Name; -} - -static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, - const TargetData *TD) { - X86MachineFunctionInfo Info; - uint64_t Size = 0; - - switch (F->getCallingConv()) { - case CallingConv::X86_StdCall: - Info.setDecorationStyle(StdCall); - break; - case CallingConv::X86_FastCall: - Info.setDecorationStyle(FastCall); - break; - default: - return Info; - } - - unsigned argNum = 1; - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI, ++argNum) { - const Type* Ty = AI->getType(); - - // 'Dereference' type in case of byval parameter attribute - if (F->paramHasAttr(argNum, Attribute::ByVal)) - Ty = cast<PointerType>(Ty)->getElementType(); - - // Size should be aligned to DWORD boundary - Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; - } - - // We're not supporting tooooo huge arguments :) - Info.setBytesToPopOnReturn((unsigned int)Size); - return Info; -} - -/// decorateName - Query FunctionInfoMap and use this information for various -/// name decoration. -void X86ATTAsmPrinter::decorateName(std::string &Name, - const GlobalValue *GV) { - const Function *F = dyn_cast<Function>(GV); - if (!F) return; - - // We don't want to decorate non-stdcall or non-fastcall functions right now - unsigned CC = F->getCallingConv(); - if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) - return; - - // Decorate names only when we're targeting Cygwin/Mingw32 targets - if (!Subtarget->isTargetCygMing()) - return; - - FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); - - const X86MachineFunctionInfo *Info; - if (info_item == FunctionInfoMap.end()) { - // Calculate apropriate function info and populate map - FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); - Info = &FunctionInfoMap[F]; - } else { - Info = &info_item->second; - } - - const FunctionType *FT = F->getFunctionType(); - switch (Info->getDecorationStyle()) { - case None: - break; - case StdCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - break; - case FastCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - - if (Name[0] == '_') { - Name[0] = '@'; - } else { - Name = '@' + Name; - } - break; - default: - assert(0 && "Unsupported DecorationStyle"); - } -} - -void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) { - unsigned FnAlign = MF.getAlignment(); - const Function *F = MF.getFunction(); - - decorateName(CurrentFnName, F); - - SwitchToSection(TAI->SectionForGlobal(F)); - switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); - case Function::InternalLinkage: // Symbols default to internal. - case Function::PrivateLinkage: - EmitAlignment(FnAlign, F); - break; - case Function::DLLExportLinkage: - case Function::ExternalLinkage: - EmitAlignment(FnAlign, F); - O << "\t.globl\t" << CurrentFnName << '\n'; - break; - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: - EmitAlignment(FnAlign, F); - if (Subtarget->isTargetDarwin()) { - O << "\t.globl\t" << CurrentFnName << '\n'; - O << TAI->getWeakDefDirective() << CurrentFnName << '\n'; - } else if (Subtarget->isTargetCygMing()) { - O << "\t.globl\t" << CurrentFnName << "\n" - "\t.linkonce discard\n"; - } else { - O << "\t.weak\t" << CurrentFnName << '\n'; - } - break; - } - - printVisibility(CurrentFnName, F->getVisibility()); - - if (Subtarget->isTargetELF()) - O << "\t.type\t" << CurrentFnName << ",@function\n"; - else if (Subtarget->isTargetCygMing()) { - O << "\t.def\t " << CurrentFnName - << ";\t.scl\t" << - (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT) - << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT) - << ";\t.endef\n"; - } - - O << CurrentFnName << ":\n"; - // Add some workaround for linkonce linkage on Cygwin\MinGW - if (Subtarget->isTargetCygMing() && - (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) - O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n"; -} - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - const Function *F = MF.getFunction(); - this->MF = &MF; - unsigned CC = F->getCallingConv(); - - SetupMachineFunction(MF); - O << "\n\n"; - - // Populate function information map. Actually, We don't want to populate - // non-stdcall or non-fastcall functions' information right now. - if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall) - FunctionInfoMap[F] = *MF.getInfo<X86MachineFunctionInfo>(); - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - if (F->hasDLLExportLinkage()) - DLLExportedFns.insert(Mang->makeNameProper(F->getName(), "")); - - // Print the 'header' of function - emitFunctionHeader(MF); - - // Emit pre-function debug and/or EH information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->BeginFunction(&MF); - - // Print out code for the function. - bool hasAnyRealCode = false; - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) { - // This is an entry block or a block that's only reachable via a - // fallthrough edge. In non-VerboseAsm mode, don't print the label. - } else { - printBasicBlockLabel(I, true, true, VerboseAsm); - O << '\n'; - } - for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); - II != IE; ++II) { - // Print the assembly for the instruction. - if (!II->isLabel()) - hasAnyRealCode = true; - printMachineInstruction(II); - } - } - - if (Subtarget->isTargetDarwin() && !hasAnyRealCode) { - // If the function is empty, then we need to emit *something*. Otherwise, - // the function's label might be associated with something that it wasn't - // meant to be associated with. We emit a noop in this situation. - // We are assuming inline asms are code. - O << "\tnop\n"; - } - - if (TAI->hasDotTypeDotSizeDirective()) - O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; - - // Emit post-function debug information. - if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) - DW->EndFunction(&MF); - - // Print out jump tables referenced by the function. - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - - O.flush(); - - // We didn't modify anything. - return false; -} - -static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_; -} - -static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) { - return ST->isPICStyleStub() && TM.getRelocationModel() != Reloc::Static; -} - -/// print_pcrel_imm - This is used to print an immediate value that ends up -/// being encoded as a pc-relative value. These print slightly differently, for -/// example, a $ is not emitted. -void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: assert(0 && "Unknown pcrel immediate operand"); - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm); - return; - - case MachineOperand::MO_GlobalAddress: { - const GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - decorateName(Name, GV); - - bool needCloseParen = false; - if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - if (shouldPrintStub(TM, Subtarget)) { - // DARWIN/X86-32 in != static mode. - - // Link-once, declaration, or Weakly-linked global variables need - // non-lazily-resolved stubs - if (GV->isDeclaration() || GV->isWeakForLinker()) { - // Dynamically-resolved functions need a stub for the function. - if (isa<Function>(GV)) { - // Function stubs are no longer needed for Mac OS X 10.5 and up. - if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) { - O << Name; - } else { - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - } - } else if (GV->hasHiddenVisibility()) { - if (!GV->isDeclaration() && !GV->hasCommonLinkage()) - // Definition is not definitely in the current translation unit. - O << Name; - else { - HiddenGVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - - if (shouldPrintPLT(TM, Subtarget)) { - // Assemble call via PLT for externally visible symbols - if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() && - !GV->hasLocalLinkage()) - O << "@PLT"; - } - if (Subtarget->isTargetCygMing() && GV->isDeclaration()) - // Save function name for later type emission - FnStubs.insert(Name); - } - - printOffset(MO.getOffset()); - - if (needCloseParen) - O << ')'; - return; - } - - case MachineOperand::MO_ExternalSymbol: { - bool needCloseParen = false; - std::string Name(TAI->getGlobalPrefix()); - Name += MO.getSymbolName(); - // Print function stub suffix unless it's Mac OS X 10.5 and up. - if (shouldPrintStub(TM, Subtarget) && - // DARWIN/X86-32 in != static mode. - !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) { - - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - return; - } - - if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - O << Name; - - if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) { - O << " + [.-"; - PrintPICBaseSymbol(); - O << ']'; - } - - if (shouldPrintPLT(TM, Subtarget)) - O << "@PLT"; - - if (needCloseParen) - O << ')'; - - return; - } - } -} - -void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier) { - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: assert(0 && "unknown operand type!"); - case MachineOperand::MO_Register: { - assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Virtual registers should not make it this far!"); - O << '%'; - unsigned Reg = MO.getReg(); - if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { - MVT VT = (strcmp(Modifier+6,"64") == 0) ? - MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : - ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); - Reg = getX86SubSuperRegister(Reg, VT); - } - O << TRI->getAsmName(Reg); - return; - } - - case MachineOperand::MO_Immediate: - if (!Modifier || (strcmp(Modifier, "debug") && - strcmp(Modifier, "mem"))) - O << '$'; - O << MO.getImm(); - return; - case MachineOperand::MO_JumpTableIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' - << MO.getIndex(); - break; - } - case MachineOperand::MO_ConstantPoolIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << '$'; - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << MO.getIndex(); - - printOffset(MO.getOffset()); - break; - } - case MachineOperand::MO_GlobalAddress: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - - const GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - decorateName(Name, GV); - - bool needCloseParen = false; - if (!isMemOp) - O << '$'; - else if (Name[0] == '$') { - // The name begins with a dollar-sign. In order to avoid having it look - // like an integer immediate to the assembler, enclose it in parens. - O << '('; - needCloseParen = true; - } - - if (shouldPrintStub(TM, Subtarget)) { - // DARWIN/X86-32 in != static mode. - - // Link-once, declaration, or Weakly-linked global variables need - // non-lazily-resolved stubs - if (GV->isDeclaration() || GV->isWeakForLinker()) { - // Dynamically-resolved functions need a stub for the function. - if (GV->hasHiddenVisibility()) { - if (!GV->isDeclaration() && !GV->hasCommonLinkage()) - // Definition is not definitely in the current translation unit. - O << Name; - else { - HiddenGVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - } - - if (TM.getRelocationModel() == Reloc::PIC_) { - O << '-'; - PrintPICBaseSymbol(); - } - } else { - if (GV->hasDLLImportLinkage()) - O << "__imp_"; - O << Name; - } - - printOffset(MO.getOffset()); - - if (needCloseParen) - O << ')'; - - break; - } - case MachineOperand::MO_ExternalSymbol: - /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated - /// by _GLOBAL_OFFSET_TABLE_ on X86-32. All others are call operands, which - /// are pcrel_imm's. - assert(!Subtarget->is64Bit() && !Subtarget->isPICStyleRIPRel()); - // These are never used as memory operands. - assert(!(Modifier && !strcmp(Modifier, "mem"))); - - O << '$'; - O << TAI->getGlobalPrefix(); - O << MO.getSymbolName(); - break; - } - - switch (MO.getTargetFlags()) { - default: - assert(0 && "Unknown target flag on GV operand"); - case X86II::MO_NO_FLAG: - break; - case X86II::MO_GOT_ABSOLUTE_ADDRESS: - O << " + [.-"; - PrintPICBaseSymbol(); - O << ']'; - break; - case X86II::MO_PIC_BASE_OFFSET: - O << '-'; - PrintPICBaseSymbol(); - break; - case X86II::MO_TLSGD: O << "@TLSGD"; break; - case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; - case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; - case X86II::MO_TPOFF: O << "@TPOFF"; break; - case X86II::MO_NTPOFF: O << "@NTPOFF"; break; - case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; - case X86II::MO_GOT: O << "@GOT"; break; - case X86II::MO_GOTOFF: O << "@GOTOFF"; break; - } -} - -void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { - unsigned char value = MI->getOperand(Op).getImm(); - assert(value <= 7 && "Invalid ssecc argument!"); - switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; - } -} - -void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier) { - MachineOperand BaseReg = MI->getOperand(Op); - MachineOperand IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - if (DispSpec.isGlobal() || - DispSpec.isCPI() || - DispSpec.isJTI() || - DispSpec.isSymbol()) { - printOperand(MI, Op+3, "mem"); - } else { - int DispVal = DispSpec.getImm(); - if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) - O << DispVal; - } - - if ((IndexReg.getReg() || BaseReg.getReg()) && - (Modifier == 0 || strcmp(Modifier, "no-rip"))) { - unsigned ScaleVal = MI->getOperand(Op+1).getImm(); - unsigned BaseRegOperand = 0, IndexRegOperand = 2; - - // There are cases where we can end up with ESP/RSP in the indexreg slot. - // If this happens, swap the base/index register to support assemblers that - // don't work when the index is *SP. - if (IndexReg.getReg() == X86::ESP || IndexReg.getReg() == X86::RSP) { - assert(ScaleVal == 1 && "Scale not supported for stack pointer!"); - std::swap(BaseReg, IndexReg); - std::swap(BaseRegOperand, IndexRegOperand); - } - - O << '('; - if (BaseReg.getReg()) - printOperand(MI, Op+BaseRegOperand, Modifier); - - if (IndexReg.getReg()) { - O << ','; - printOperand(MI, Op+IndexRegOperand, Modifier); - if (ScaleVal != 1) - O << ',' << ScaleVal; - } - O << ')'; - } -} - -void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier) { - assert(isMem(MI, Op) && "Invalid memory reference!"); - MachineOperand Segment = MI->getOperand(Op+4); - if (Segment.getReg()) { - printOperand(MI, Op+4, Modifier); - O << ':'; - } - printLeaMemReference(MI, Op, Modifier); -} - -void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const { - if (!TAI->getSetDirective()) - return; - - // We don't need .set machinery if we have GOT-style relocations - if (Subtarget->isPICStyleGOT()) - return; - - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; - printBasicBlockLabel(MBB, false, false, false); - if (Subtarget->isPICStyleRIPRel()) - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '\n'; - else { - O << '-'; - PrintPICBaseSymbol(); - O << '\n'; - } -} - - -void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - PrintPICBaseSymbol(); - O << '\n'; - PrintPICBaseSymbol(); - O << ':'; -} - - -void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, - unsigned uid) const -{ - const char *JTEntryDirective = MJTI->getEntrySize() == 4 ? - TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); - - O << JTEntryDirective << ' '; - - if (TM.getRelocationModel() == Reloc::PIC_) { - if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStub()) { - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << uid << "_set_" << MBB->getNumber(); - } else if (Subtarget->isPICStyleGOT()) { - printBasicBlockLabel(MBB, false, false, false); - O << "@GOTOFF"; - } else - assert(0 && "Don't know how to print MBB label for this PIC mode"); - } else - printBasicBlockLabel(MBB, false, false, false); -} - -bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) { - unsigned Reg = MO.getReg(); - switch (Mode) { - default: return true; // Unknown mode. - case 'b': // Print QImode register - Reg = getX86SubSuperRegister(Reg, MVT::i8); - break; - case 'h': // Print QImode high register - Reg = getX86SubSuperRegister(Reg, MVT::i8, true); - break; - case 'w': // Print HImode register - Reg = getX86SubSuperRegister(Reg, MVT::i16); - break; - case 'k': // Print SImode register - Reg = getX86SubSuperRegister(Reg, MVT::i32); - break; - case 'q': // Print DImode register - Reg = getX86SubSuperRegister(Reg, MVT::i64); - break; - } - - O << '%'<< TRI->getAsmName(Reg); - return false; -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'c': // Don't print "$" before a global var name or constant. - printOperand(MI, OpNo, "mem"); - return false; - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - case 'q': // Print DImode register - if (MI->getOperand(OpNo).isReg()) - return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); - printOperand(MI, OpNo); - return false; - - case 'P': // Don't print @PLT, but do print as memory. - printOperand(MI, OpNo, "mem"); - return false; - - case 'n': { // Negate the immediate or print a '-' before the operand. - // Note: this is a temporary solution. It should be handled target - // independently as part of the 'MC' work. - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.isImm()) { - O << -MO.getImm(); - return false; - } - O << '-'; - } - } - } - - printOperand(MI, OpNo); - return false; -} - -bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - case 'q': // Print SImode register - // These only apply to registers, ignore on mem. - break; - case 'P': // Don't print @PLT, but do print as memory. - printMemReference(MI, OpNo, "no-rip"); - return false; - } - } - printMemReference(MI, OpNo); - return false; -} - -static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) { - // Convert registers in the addr mode according to subreg64. - for (unsigned i = 0; i != 4; ++i) { - if (!MI->getOperand(i).isReg()) continue; - - unsigned Reg = MI->getOperand(i).getReg(); - if (Reg == 0) continue; - - MI->getOperand(i).setReg(getX86SubSuperRegister(Reg, MVT::i64)); - } -} - -/// printMachineInstruction -- Print out a single X86 LLVM instruction MI in -/// AT&T syntax to the current output stream. -/// -void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - if (NewAsmPrinter) { - if (MI->getOpcode() == TargetInstrInfo::INLINEASM) { - O << "\t"; - printInlineAsm(MI); - return; - } else if (MI->isLabel()) { - printLabel(MI); - return; - } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) { - printDeclare(MI); - return; - } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { - printImplicitDef(MI); - return; - } - - O << "NEW: "; - MCInst TmpInst; - - TmpInst.setOpcode(MI->getOpcode()); - - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - - MCOperand MCOp; - if (MO.isReg()) { - MCOp.MakeReg(MO.getReg()); - } else if (MO.isImm()) { - MCOp.MakeImm(MO.getImm()); - } else if (MO.isMBB()) { - MCOp.MakeMBBLabel(getFunctionNumber(), MO.getMBB()->getNumber()); - } else { - assert(0 && "Unimp"); - } - - TmpInst.addOperand(MCOp); - } - - switch (TmpInst.getOpcode()) { - case X86::LEA64_32r: - // Handle the 'subreg rewriting' for the lea64_32mem operand. - lower_lea64_32mem(&TmpInst, 1); - break; - } - - // FIXME: Convert TmpInst. - printInstruction(&TmpInst); - O << "OLD: "; - } - - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -/// doInitialization -bool X86ATTAsmPrinter::doInitialization(Module &M) { - if (NewAsmPrinter) { - Context = new MCContext(); - // FIXME: Send this to "O" instead of outs(). For now, we force it to - // stdout to make it easy to compare. - Streamer = createAsmStreamer(*Context, outs()); - } - - return AsmPrinter::doInitialization(M); -} - -void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { - const TargetData *TD = TM.getTargetData(); - - if (!GVar->hasInitializer()) - return; // External global require no code - - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(GVar)) { - if (Subtarget->isTargetDarwin() && - TM.getRelocationModel() == Reloc::Static) { - if (GVar->getName() == "llvm.global_ctors") - O << ".reference .constructors_used\n"; - else if (GVar->getName() == "llvm.global_dtors") - O << ".reference .destructors_used\n"; - } - return; - } - - std::string name = Mang->getValueName(GVar); - Constant *C = GVar->getInitializer(); - if (isa<MDNode>(C) || isa<MDString>(C)) - return; - const Type *Type = C->getType(); - unsigned Size = TD->getTypeAllocSize(Type); - unsigned Align = TD->getPreferredAlignmentLog(GVar); - - printVisibility(name, GVar->getVisibility()); - - if (Subtarget->isTargetELF()) - O << "\t.type\t" << name << ",@object\n"; - - SwitchToSection(TAI->SectionForGlobal(GVar)); - - if (C->isNullValue() && !GVar->hasSection() && - !(Subtarget->isTargetDarwin() && - TAI->SectionKindForGlobal(GVar) == SectionKind::RODataMergeStr)) { - // FIXME: This seems to be pretty darwin-specific - if (GVar->hasExternalLinkage()) { - if (const char *Directive = TAI->getZeroFillDirective()) { - O << "\t.globl " << name << '\n'; - O << Directive << "__DATA, __common, " << name << ", " - << Size << ", " << Align << '\n'; - return; - } - } - - if (!GVar->isThreadLocal() && - (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (TAI->getLCOMMDirective() != NULL) { - if (GVar->hasLocalLinkage()) { - O << TAI->getLCOMMDirective() << name << ',' << Size; - if (Subtarget->isTargetDarwin()) - O << ',' << Align; - } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) { - O << "\t.globl " << name << '\n' - << TAI->getWeakDefDirective() << name << '\n'; - EmitAlignment(Align, GVar); - O << name << ":"; - if (VerboseAsm) { - O << "\t\t\t\t" << TAI->getCommentString() << ' '; - PrintUnmangledNameSafely(GVar, O); - } - O << '\n'; - EmitGlobalConstant(C); - return; - } else { - O << TAI->getCOMMDirective() << name << ',' << Size; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - } else { - if (!Subtarget->isTargetCygMing()) { - if (GVar->hasLocalLinkage()) - O << "\t.local\t" << name << '\n'; - } - O << TAI->getCOMMDirective() << name << ',' << Size; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); - } - if (VerboseAsm) { - O << "\t\t" << TAI->getCommentString() << ' '; - PrintUnmangledNameSafely(GVar, O); - } - O << '\n'; - return; - } - } - - switch (GVar->getLinkage()) { - case GlobalValue::CommonLinkage: - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - if (Subtarget->isTargetDarwin()) { - O << "\t.globl " << name << '\n' - << TAI->getWeakDefDirective() << name << '\n'; - } else if (Subtarget->isTargetCygMing()) { - O << "\t.globl\t" << name << "\n" - "\t.linkonce same_size\n"; - } else { - O << "\t.weak\t" << name << '\n'; - } - break; - case GlobalValue::DLLExportLinkage: - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << "\t.globl " << name << '\n'; - // FALL THROUGH - case GlobalValue::PrivateLinkage: - case GlobalValue::InternalLinkage: - break; - default: - assert(0 && "Unknown linkage type!"); - } - - EmitAlignment(Align, GVar); - O << name << ":"; - if (VerboseAsm){ - O << "\t\t\t\t" << TAI->getCommentString() << ' '; - PrintUnmangledNameSafely(GVar, O); - } - O << '\n'; - if (TAI->hasDotTypeDotSizeDirective()) - O << "\t.size\t" << name << ", " << Size << '\n'; - - EmitGlobalConstant(C); -} - -bool X86ATTAsmPrinter::doFinalization(Module &M) { - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - printModuleLevelGV(I); - - if (I->hasDLLExportLinkage()) - DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),"")); - } - - if (Subtarget->isTargetDarwin()) { - SwitchToDataSection(""); - - // Add the (possibly multiple) personalities to the set of global value - // stubs. Only referenced functions get into the Personalities list. - if (TAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) { - const std::vector<Function*> &Personalities = MMI->getPersonalities(); - for (unsigned i = 0, e = Personalities.size(); i != e; ++i) { - if (Personalities[i] == 0) - continue; - std::string Name = Mang->getValueName(Personalities[i]); - decorateName(Name, Personalities[i]); - GVStubs.insert(Name); - } - } - - // Output stubs for dynamically-linked functions - if (!FnStubs.empty()) { - for (StringSet<>::iterator I = FnStubs.begin(), E = FnStubs.end(); - I != E; ++I) { - SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs," - "self_modifying_code+pure_instructions,5", 0); - const char *Name = I->getKeyData(); - printSuffixedName(Name, "$stub"); - O << ":\n" - "\t.indirect_symbol " << Name << "\n" - "\thlt ; hlt ; hlt ; hlt ; hlt\n"; - } - O << '\n'; - } - - // Output stubs for external and common global variables. - if (!GVStubs.empty()) { - SwitchToDataSection( - "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers"); - for (StringSet<>::iterator I = GVStubs.begin(), E = GVStubs.end(); - I != E; ++I) { - const char *Name = I->getKeyData(); - printSuffixedName(Name, "$non_lazy_ptr"); - O << ":\n\t.indirect_symbol " << Name << "\n\t.long\t0\n"; - } - } - - if (!HiddenGVStubs.empty()) { - SwitchToSection(TAI->getDataSection()); - EmitAlignment(2); - for (StringSet<>::iterator I = HiddenGVStubs.begin(), - E = HiddenGVStubs.end(); I != E; ++I) { - const char *Name = I->getKeyData(); - printSuffixedName(Name, "$non_lazy_ptr"); - O << ":\n" << TAI->getData32bitsDirective() << Name << '\n'; - } - } - - // Funny Darwin hack: This flag tells the linker that no global symbols - // contain code that falls through to other global symbols (e.g. the obvious - // implementation of multiple entry points). If this doesn't occur, the - // linker can safely perform dead code stripping. Since LLVM never - // generates code that does this, it is always safe to set. - O << "\t.subsections_via_symbols\n"; - } else if (Subtarget->isTargetCygMing()) { - // Emit type information for external functions - for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i) { - O << "\t.def\t " << i->getKeyData() - << ";\t.scl\t" << COFF::C_EXT - << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT) - << ";\t.endef\n"; - } - } - - - // Output linker support code for dllexported globals on windows. - if (!DLLExportedGVs.empty()) { - SwitchToDataSection(".section .drectve"); - - for (StringSet<>::iterator i = DLLExportedGVs.begin(), - e = DLLExportedGVs.end(); i != e; ++i) - O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n"; - } - - if (!DLLExportedFns.empty()) { - SwitchToDataSection(".section .drectve"); - - for (StringSet<>::iterator i = DLLExportedFns.begin(), - e = DLLExportedFns.end(); - i != e; ++i) - O << "\t.ascii \" -export:" << i->getKeyData() << "\"\n"; - } - - // Do common shutdown. - bool Changed = AsmPrinter::doFinalization(M); - - if (NewAsmPrinter) { - Streamer->Finish(); - - delete Streamer; - delete Context; - Streamer = 0; - Context = 0; - } - - return Changed; -} - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter.inc" diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h deleted file mode 100644 index f47daf1..0000000 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h +++ /dev/null @@ -1,226 +0,0 @@ -//===-- X86ATTAsmPrinter.h - Convert X86 LLVM code to AT&T assembly -------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// AT&T assembly code printer class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86ATTASMPRINTER_H -#define X86ATTASMPRINTER_H - -#include "../X86.h" -#include "../X86MachineFunctionInfo.h" -#include "../X86TargetMachine.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - -class MachineJumpTableInfo; -class MCContext; -class MCInst; -class MCStreamer; - -class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { - const X86Subtarget *Subtarget; - - MCContext *Context; - MCStreamer *Streamer; - public: - explicit X86ATTAsmPrinter(raw_ostream &O, X86TargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V) { - Subtarget = &TM.getSubtarget<X86Subtarget>(); - Context = 0; - Streamer = 0; - } - - virtual const char *getPassName() const { - return "X86 AT&T-Style Assembly Printer"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - if (Subtarget->isTargetDarwin() || - Subtarget->isTargetELF() || - Subtarget->isTargetCygMing()) { - AU.addRequired<MachineModuleInfo>(); - } - AU.addRequired<DwarfWriter>(); - AsmPrinter::getAnalysisUsage(AU); - } - - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - - // New MCInst printing stuff. - bool printInstruction(const MCInst *MI); - - void printOperand(const MCInst *MI, unsigned OpNo, - const char *Modifier = 0); - void printMemReference(const MCInst *MI, unsigned Op); - void printLeaMemReference(const MCInst *MI, unsigned Op); - void printSSECC(const MCInst *MI, unsigned Op); - void printPICLabel(const MCInst *MI, unsigned Op); - void print_pcrel_imm(const MCInst *MI, unsigned OpNo); - - void printi8mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi16mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi32mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi64mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi128mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf32mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf64mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf80mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf128mem(const MCInst *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printlea32mem(const MCInst *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64mem(const MCInst *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64_32mem(const MCInst *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - - - - // These methods are used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier = 0); - void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); - void printi8mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi16mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi32mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi64mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi128mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printi256mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf32mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf64mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf80mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf128mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printf256mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } - void printlea32mem(const MachineInstr *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64mem(const MachineInstr *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo); - } - void printlea64_32mem(const MachineInstr *MI, unsigned OpNo) { - printLeaMemReference(MI, OpNo, "subreg64"); - } - - bool printAsmMRegister(const MachineOperand &MO, char Mode); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - - void printMachineInstruction(const MachineInstr *MI); - void printSSECC(const MachineInstr *MI, unsigned Op); - void printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const; - void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const { - AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); - } - void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, - unsigned uid) const; - - void printPICLabel(const MachineInstr *MI, unsigned Op); - void printModuleLevelGV(const GlobalVariable* GVar); - - void PrintPICBaseSymbol() const; - - bool runOnMachineFunction(MachineFunction &F); - - void emitFunctionHeader(const MachineFunction &MF); - - // Necessary for Darwin to print out the apprioriate types of linker stubs - StringSet<> FnStubs, GVStubs, HiddenGVStubs; - - // Necessary for dllexport support - StringSet<> DLLExportedFns, DLLExportedGVs; - - // We have to propagate some information about MachineFunction to - // AsmPrinter. It's ok, when we're printing the function, since we have - // access to MachineFunction and can get the appropriate MachineFunctionInfo. - // Unfortunately, this is not possible when we're printing reference to - // Function (e.g. calling it and so on). Even more, there is no way to get the - // corresponding MachineFunctions: it can even be not created at all. That's - // why we should use additional structure, when we're collecting all necessary - // information. - // - // This structure is using e.g. for name decoration for stdcall & fastcall'ed - // function, since we have to use arguments' size for decoration. - typedef std::map<const Function*, X86MachineFunctionInfo> FMFInfoMap; - FMFInfoMap FunctionInfoMap; - - void decorateName(std::string& Name, const GlobalValue* GV); -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp deleted file mode 100644 index 9d4df93..0000000 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp +++ /dev/null @@ -1,633 +0,0 @@ -//===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly --===// -// -// 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 Intel format assembly language. -// This printer is the output mechanism used by `llc'. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "X86IntelAsmPrinter.h" -#include "X86InstrInfo.h" -#include "X86TargetAsmInfo.h" -#include "X86.h" -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetOptions.h" -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -static X86MachineFunctionInfo calculateFunctionInfo(const Function *F, - const TargetData *TD) { - X86MachineFunctionInfo Info; - uint64_t Size = 0; - - switch (F->getCallingConv()) { - case CallingConv::X86_StdCall: - Info.setDecorationStyle(StdCall); - break; - case CallingConv::X86_FastCall: - Info.setDecorationStyle(FastCall); - break; - default: - return Info; - } - - unsigned argNum = 1; - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI, ++argNum) { - const Type* Ty = AI->getType(); - - // 'Dereference' type in case of byval parameter attribute - if (F->paramHasAttr(argNum, Attribute::ByVal)) - Ty = cast<PointerType>(Ty)->getElementType(); - - // Size should be aligned to DWORD boundary - Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4; - } - - // We're not supporting tooooo huge arguments :) - Info.setBytesToPopOnReturn((unsigned int)Size); - return Info; -} - - -/// decorateName - Query FunctionInfoMap and use this information for various -/// name decoration. -void X86IntelAsmPrinter::decorateName(std::string &Name, - const GlobalValue *GV) { - const Function *F = dyn_cast<Function>(GV); - if (!F) return; - - // We don't want to decorate non-stdcall or non-fastcall functions right now - unsigned CC = F->getCallingConv(); - if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall) - return; - - FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F); - - const X86MachineFunctionInfo *Info; - if (info_item == FunctionInfoMap.end()) { - // Calculate apropriate function info and populate map - FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData()); - Info = &FunctionInfoMap[F]; - } else { - Info = &info_item->second; - } - - const FunctionType *FT = F->getFunctionType(); - switch (Info->getDecorationStyle()) { - case None: - break; - case StdCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - break; - case FastCall: - // "Pure" variadic functions do not receive @0 suffix. - if (!FT->isVarArg() || (FT->getNumParams() == 0) || - (FT->getNumParams() == 1 && F->hasStructRetAttr())) - Name += '@' + utostr_32(Info->getBytesToPopOnReturn()); - - if (Name[0] == '_') - Name[0] = '@'; - else - Name = '@' + Name; - - break; - default: - assert(0 && "Unsupported DecorationStyle"); - } -} - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - this->MF = &MF; - SetupMachineFunction(MF); - O << "\n\n"; - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - const Function *F = MF.getFunction(); - unsigned CC = F->getCallingConv(); - unsigned FnAlign = MF.getAlignment(); - - // Populate function information map. Actually, We don't want to populate - // non-stdcall or non-fastcall functions' information right now. - if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall) - FunctionInfoMap[F] = *MF.getInfo<X86MachineFunctionInfo>(); - - decorateName(CurrentFnName, F); - - SwitchToTextSection("_text", F); - switch (F->getLinkage()) { - default: assert(0 && "Unsupported linkage type!"); - case Function::PrivateLinkage: - case Function::InternalLinkage: - EmitAlignment(FnAlign); - break; - case Function::DLLExportLinkage: - DLLExportedFns.insert(CurrentFnName); - //FALLS THROUGH - case Function::ExternalLinkage: - O << "\tpublic " << CurrentFnName << "\n"; - EmitAlignment(FnAlign); - break; - } - - O << CurrentFnName << "\tproc near\n"; - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block if there are any predecessors. - if (!I->pred_empty()) { - printBasicBlockLabel(I, true, true); - O << '\n'; - } - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - printMachineInstruction(II); - } - } - - // Print out jump tables referenced by the function. - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - - O << CurrentFnName << "\tendp\n"; - - O.flush(); - - // We didn't modify anything. - return false; -} - -void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) { - unsigned char value = MI->getOperand(Op).getImm(); - assert(value <= 7 && "Invalid ssecc argument!"); - switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; - } -} - -void X86IntelAsmPrinter::printOp(const MachineOperand &MO, - const char *Modifier) { - switch (MO.getType()) { - case MachineOperand::MO_Register: { - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) { - unsigned Reg = MO.getReg(); - if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { - MVT VT = (strcmp(Modifier,"subreg64") == 0) ? - MVT::i64 : ((strcmp(Modifier, "subreg32") == 0) ? MVT::i32 : - ((strcmp(Modifier,"subreg16") == 0) ? MVT::i16 :MVT::i8)); - Reg = getX86SubSuperRegister(Reg, VT); - } - O << TRI->getName(Reg); - } else - O << "reg" << MO.getReg(); - return; - } - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_JumpTableIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << "OFFSET "; - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << "_" << MO.getIndex(); - return; - } - case MachineOperand::MO_ConstantPoolIndex: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (!isMemOp) O << "OFFSET "; - O << "[" << TAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getIndex(); - printOffset(MO.getOffset()); - O << "]"; - return; - } - case MachineOperand::MO_GlobalAddress: { - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - - decorateName(Name, GV); - - if (!isMemOp) O << "OFFSET "; - if (GV->hasDLLImportLinkage()) { - // FIXME: This should be fixed with full support of stdcall & fastcall - // CC's - O << "__imp_"; - } - O << Name; - printOffset(MO.getOffset()); - return; - } - case MachineOperand::MO_ExternalSymbol: { - O << TAI->getGlobalPrefix() << MO.getSymbolName(); - return; - } - default: - O << "<unknown operand type>"; return; - } -} - -void X86IntelAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo){ - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: assert(0 && "Unknown pcrel immediate operand"); - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; - - case MachineOperand::MO_GlobalAddress: { - GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); - decorateName(Name, GV); - - if (GV->hasDLLImportLinkage()) { - // FIXME: This should be fixed with full support of stdcall & fastcall - // CC's - O << "__imp_"; - } - O << Name; - printOffset(MO.getOffset()); - return; - } - - case MachineOperand::MO_ExternalSymbol: - O << TAI->getGlobalPrefix() << MO.getSymbolName(); - return; - } -} - - -void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr *MI, - unsigned Op, - const char *Modifier) { - const MachineOperand &BaseReg = MI->getOperand(Op); - int ScaleVal = MI->getOperand(Op+1).getImm(); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - O << "["; - bool NeedPlus = false; - if (BaseReg.getReg()) { - printOp(BaseReg, Modifier); - NeedPlus = true; - } - - if (IndexReg.getReg()) { - if (NeedPlus) O << " + "; - if (ScaleVal != 1) - O << ScaleVal << "*"; - printOp(IndexReg, Modifier); - NeedPlus = true; - } - - if (DispSpec.isGlobal() || DispSpec.isCPI() || - DispSpec.isJTI()) { - if (NeedPlus) - O << " + "; - printOp(DispSpec, "mem"); - } else { - int DispVal = DispSpec.getImm(); - if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { - if (NeedPlus) { - if (DispVal > 0) - O << " + "; - else { - O << " - "; - DispVal = -DispVal; - } - } - O << DispVal; - } - } - O << "]"; -} - -void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier) { - assert(isMem(MI, Op) && "Invalid memory reference!"); - MachineOperand Segment = MI->getOperand(Op+4); - if (Segment.getReg()) { - printOperand(MI, Op+4, Modifier); - O << ':'; - } - printLeaMemReference(MI, Op, Modifier); -} - -void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const { - if (!TAI->getSetDirective()) - return; - - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; - printBasicBlockLabel(MBB, false, false, false); - O << '-' << "\"L" << getFunctionNumber() << "$pb\"'\n"; -} - -void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - O << "L" << getFunctionNumber() << "$pb\n"; - O << "L" << getFunctionNumber() << "$pb:"; -} - -bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, - const char Mode) { - unsigned Reg = MO.getReg(); - switch (Mode) { - default: return true; // Unknown mode. - case 'b': // Print QImode register - Reg = getX86SubSuperRegister(Reg, MVT::i8); - break; - case 'h': // Print QImode high register - Reg = getX86SubSuperRegister(Reg, MVT::i8, true); - break; - case 'w': // Print HImode register - Reg = getX86SubSuperRegister(Reg, MVT::i16); - break; - case 'k': // Print SImode register - Reg = getX86SubSuperRegister(Reg, MVT::i32); - break; - } - - O << TRI->getName(Reg); - return false; -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); - } - } - - printOperand(MI, OpNo); - return false; -} - -bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier. - printMemReference(MI, OpNo); - return false; -} - -/// printMachineInstruction -- Print out a single X86 LLVM instruction -/// MI in Intel syntax to the current output stream. -/// -void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -bool X86IntelAsmPrinter::doInitialization(Module &M) { - bool Result = AsmPrinter::doInitialization(M); - - Mang->markCharUnacceptable('.'); - - O << "\t.686\n\t.MMX\n\t.XMM\n\t.model flat\n\n"; - - // Emit declarations for external functions. - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->isDeclaration()) { - std::string Name = Mang->getValueName(I); - decorateName(Name, I); - - O << "\tEXTERN " ; - if (I->hasDLLImportLinkage()) { - O << "__imp_"; - } - O << Name << ":near\n"; - } - - // Emit declarations for external globals. Note that VC++ always declares - // external globals to have type byte, and if that's good enough for VC++... - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (I->isDeclaration()) { - std::string Name = Mang->getValueName(I); - - O << "\tEXTERN " ; - if (I->hasDLLImportLinkage()) { - O << "__imp_"; - } - O << Name << ":byte\n"; - } - } - - return Result; -} - -bool X86IntelAsmPrinter::doFinalization(Module &M) { - const TargetData *TD = TM.getTargetData(); - - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (I->isDeclaration()) continue; // External global require no code - - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(I)) - continue; - - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - unsigned Align = TD->getPreferredAlignmentLog(I); - bool bCustomSegment = false; - - switch (I->getLinkage()) { - case GlobalValue::CommonLinkage: - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - SwitchToDataSection(""); - O << name << "?\tSEGEMNT PARA common 'COMMON'\n"; - bCustomSegment = true; - // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 - // are also available. - break; - case GlobalValue::AppendingLinkage: - SwitchToDataSection(""); - O << name << "?\tSEGMENT PARA public 'DATA'\n"; - bCustomSegment = true; - // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 - // are also available. - break; - case GlobalValue::DLLExportLinkage: - DLLExportedGVs.insert(name); - // FALL THROUGH - case GlobalValue::ExternalLinkage: - O << "\tpublic " << name << "\n"; - // FALL THROUGH - case GlobalValue::InternalLinkage: - SwitchToSection(TAI->getDataSection()); - break; - default: - assert(0 && "Unknown linkage type!"); - } - - if (!bCustomSegment) - EmitAlignment(Align, I); - - O << name << ":"; - if (VerboseAsm) - O << "\t\t\t\t" << TAI->getCommentString() - << " " << I->getName(); - O << '\n'; - - EmitGlobalConstant(C); - - if (bCustomSegment) - O << name << "?\tends\n"; - } - - // Output linker support code for dllexported globals - if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) { - SwitchToDataSection(""); - O << "; WARNING: The following code is valid only with MASM v8.x" - << "and (possible) higher\n" - << "; This version of MASM is usually shipped with Microsoft " - << "Visual Studio 2005\n" - << "; or (possible) further versions. Unfortunately, there is no " - << "way to support\n" - << "; dllexported symbols in the earlier versions of MASM in fully " - << "automatic way\n\n"; - O << "_drectve\t segment info alias('.drectve')\n"; - } - - for (StringSet<>::iterator i = DLLExportedGVs.begin(), - e = DLLExportedGVs.end(); - i != e; ++i) - O << "\t db ' /EXPORT:" << i->getKeyData() << ",data'\n"; - - for (StringSet<>::iterator i = DLLExportedFns.begin(), - e = DLLExportedFns.end(); - i != e; ++i) - O << "\t db ' /EXPORT:" << i->getKeyData() << "'\n"; - - if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) - O << "_drectve\t ends\n"; - - // Bypass X86SharedAsmPrinter::doFinalization(). - bool Result = AsmPrinter::doFinalization(M); - SwitchToDataSection(""); - O << "\tend\n"; - return Result; -} - -void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const { - unsigned NumElts = CVA->getNumOperands(); - if (NumElts) { - // ML does not have escape sequences except '' for '. It also has a maximum - // string length of 255. - unsigned len = 0; - bool inString = false; - for (unsigned i = 0; i < NumElts; i++) { - int n = cast<ConstantInt>(CVA->getOperand(i))->getZExtValue() & 255; - if (len == 0) - O << "\tdb "; - - if (n >= 32 && n <= 127) { - if (!inString) { - if (len > 0) { - O << ",'"; - len += 2; - } else { - O << "'"; - len++; - } - inString = true; - } - if (n == '\'') { - O << "'"; - len++; - } - O << char(n); - } else { - if (inString) { - O << "'"; - len++; - inString = false; - } - if (len > 0) { - O << ","; - len++; - } - O << n; - len += 1 + (n > 9) + (n > 99); - } - - if (len > 60) { - if (inString) { - O << "'"; - inString = false; - } - O << "\n"; - len = 0; - } - } - - if (len > 0) { - if (inString) - O << "'"; - O << "\n"; - } - } -} - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter1.inc" diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h deleted file mode 100644 index a724c3c..0000000 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h +++ /dev/null @@ -1,162 +0,0 @@ -//===-- X86IntelAsmPrinter.h - Convert X86 LLVM code to Intel assembly ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Intel assembly code printer class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86INTELASMPRINTER_H -#define X86INTELASMPRINTER_H - -#include "../X86.h" -#include "../X86MachineFunctionInfo.h" -#include "../X86TargetMachine.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvm { - -struct VISIBILITY_HIDDEN X86IntelAsmPrinter : public AsmPrinter { - explicit X86IntelAsmPrinter(raw_ostream &O, X86TargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V) {} - - virtual const char *getPassName() const { - return "X86 Intel-Style Assembly Printer"; - } - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - // This method is used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, - const char *Modifier = 0) { - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.isReg()) { - assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Not physreg??"); - O << TM.getRegisterInfo()->get(MO.getReg()).Name; // Capitalized names - } else { - printOp(MO, Modifier); - } - } - - void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); - - - void printi8mem(const MachineInstr *MI, unsigned OpNo) { - O << "BYTE PTR "; - printMemReference(MI, OpNo); - } - void printi16mem(const MachineInstr *MI, unsigned OpNo) { - O << "WORD PTR "; - printMemReference(MI, OpNo); - } - void printi32mem(const MachineInstr *MI, unsigned OpNo) { - O << "DWORD PTR "; - printMemReference(MI, OpNo); - } - void printi64mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printMemReference(MI, OpNo); - } - void printi128mem(const MachineInstr *MI, unsigned OpNo) { - O << "XMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printi256mem(const MachineInstr *MI, unsigned OpNo) { - O << "YMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printf32mem(const MachineInstr *MI, unsigned OpNo) { - O << "DWORD PTR "; - printMemReference(MI, OpNo); - } - void printf64mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printMemReference(MI, OpNo); - } - void printf80mem(const MachineInstr *MI, unsigned OpNo) { - O << "XWORD PTR "; - printMemReference(MI, OpNo); - } - void printf128mem(const MachineInstr *MI, unsigned OpNo) { - O << "XMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printf256mem(const MachineInstr *MI, unsigned OpNo) { - O << "YMMWORD PTR "; - printMemReference(MI, OpNo); - } - void printlea32mem(const MachineInstr *MI, unsigned OpNo) { - O << "DWORD PTR "; - printLeaMemReference(MI, OpNo); - } - void printlea64mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printLeaMemReference(MI, OpNo); - } - void printlea64_32mem(const MachineInstr *MI, unsigned OpNo) { - O << "QWORD PTR "; - printLeaMemReference(MI, OpNo, "subreg64"); - } - - bool printAsmMRegister(const MachineOperand &MO, const char Mode); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, const char *Modifier = 0); - void printSSECC(const MachineInstr *MI, unsigned Op); - void printMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printLeaMemReference(const MachineInstr *MI, unsigned Op, - const char *Modifier=NULL); - void printPICJumpTableSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const; - void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const { - AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); - } - void printPICLabel(const MachineInstr *MI, unsigned Op); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - // We have to propagate some information about MachineFunction to - // AsmPrinter. It's ok, when we're printing the function, since we have - // access to MachineFunction and can get the appropriate MachineFunctionInfo. - // Unfortunately, this is not possible when we're printing reference to - // Function (e.g. calling it and so on). Even more, there is no way to get the - // corresponding MachineFunctions: it can even be not created at all. That's - // why we should use additional structure, when we're collecting all necessary - // information. - // - // This structure is using e.g. for name decoration for stdcall & fastcall'ed - // function, since we have to use arguments' size for decoration. - typedef std::map<const Function*, X86MachineFunctionInfo> FMFInfoMap; - FMFInfoMap FunctionInfoMap; - - void decorateName(std::string& Name, const GlobalValue* GV); - - virtual void EmitString(const ConstantArray *CVA) const; - - // Necessary for dllexport support - StringSet<> DLLExportedFns, DLLExportedGVs; -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp deleted file mode 100644 index f49ca15..0000000 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ /dev/null @@ -1,429 +0,0 @@ -//===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the X86TargetAsmInfo properties. -// -//===----------------------------------------------------------------------===// - -#include "X86TargetAsmInfo.h" -#include "X86TargetMachine.h" -#include "X86Subtarget.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/Module.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Dwarf.h" - -using namespace llvm; -using namespace llvm::dwarf; - -const char *const llvm::x86_asm_table[] = { - "{si}", "S", - "{di}", "D", - "{ax}", "a", - "{cx}", "c", - "{memory}", "memory", - "{flags}", "", - "{dirflag}", "", - "{fpsr}", "", - "{cc}", "cc", - 0,0}; - -X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM): - X86TargetAsmInfo<DarwinTargetAsmInfo>(TM) { - const X86Subtarget* Subtarget = &TM.getSubtarget<X86Subtarget>(); - bool is64Bit = Subtarget->is64Bit(); - - AlignmentIsInBytes = false; - TextAlignFillValue = 0x90; - - - if (!is64Bit) - Data64bitsDirective = 0; // we can't emit a 64-bit unit - ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. - ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill - if (TM.getRelocationModel() != Reloc::Static) - ConstantPoolSection = "\t.const_data"; - else - ConstantPoolSection = "\t.const\n"; - // FIXME: Why don't we always use this section? - if (is64Bit) - SixteenByteConstantSection = getUnnamedSection("\t.literal16\n", - SectionFlags::Mergeable); - LCOMMDirective = "\t.lcomm\t"; - // Leopard and above support aligned common symbols. - COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9); - HasDotTypeDotSizeDirective = false; - NonLocalEHFrameLabel = true; - if (is64Bit) { - PersonalityPrefix = ""; - PersonalitySuffix = "+4@GOTPCREL"; - } else { - PersonalityPrefix = "L"; - PersonalitySuffix = "$non_lazy_ptr"; - } - InlineAsmStart = "## InlineAsm Start"; - InlineAsmEnd = "## InlineAsm End"; - CommentString = "##"; - SetDirective = "\t.set"; - PCSymbol = "."; - UsedDirective = "\t.no_dead_strip\t"; - ProtectedDirective = "\t.globl\t"; - - SupportsDebugInformation = true; - - DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug"; - DwarfUsesInlineInfoSection = true; - - // Exceptions handling - SupportsExceptionHandling = true; - GlobalEHDirective = "\t.globl\t"; - SupportsWeakOmittedEHFrame = false; - AbsoluteEHSectionOffsets = false; - DwarfEHFrameSection = - ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; - DwarfExceptionSection = ".section __DATA,__gcc_except_tab"; -} - -unsigned -X86DarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - if (Reason == DwarfEncoding::Functions && Global) - return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); - else if (Reason == DwarfEncoding::CodeLabels || !Global) - return DW_EH_PE_pcrel; - else - return DW_EH_PE_absptr; -} - -const char * -X86DarwinTargetAsmInfo::getEHGlobalPrefix() const -{ - const X86Subtarget* Subtarget = &TM.getSubtarget<X86Subtarget>(); - if (Subtarget->getDarwinVers() > 9) - return PrivateGlobalPrefix; - else - return ""; -} - -X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM): - X86TargetAsmInfo<ELFTargetAsmInfo>(TM) { - - CStringSection = ".rodata.str"; - PrivateGlobalPrefix = ".L"; - WeakRefDirective = "\t.weak\t"; - SetDirective = "\t.set\t"; - PCSymbol = "."; - - // Set up DWARF directives - HasLEB128 = true; // Target asm supports leb128 directives (little-endian) - - // Debug Information - AbsoluteDebugSectionOffsets = true; - SupportsDebugInformation = true; - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits"; - DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits"; - DwarfLineSection = "\t.section\t.debug_line,\"\",@progbits"; - DwarfFrameSection = "\t.section\t.debug_frame,\"\",@progbits"; - DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits"; - DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits"; - DwarfStrSection = "\t.section\t.debug_str,\"\",@progbits"; - DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; - DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; - DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; - - // Exceptions handling - SupportsExceptionHandling = true; - AbsoluteEHSectionOffsets = false; - DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits"; - DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits"; - - // On Linux we must declare when we can use a non-executable stack. - if (TM.getSubtarget<X86Subtarget>().isLinux()) - NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits"; -} - -unsigned -X86ELFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - CodeModel::Model CM = TM.getCodeModel(); - bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit(); - - if (TM.getRelocationModel() == Reloc::PIC_) { - unsigned Format = 0; - - if (!is64Bit) - // 32 bit targets always encode pointers as 4 bytes - Format = DW_EH_PE_sdata4; - else { - // 64 bit targets encode pointers in 4 bytes iff: - // - code model is small OR - // - code model is medium and we're emitting externally visible symbols - // or any code symbols - if (CM == CodeModel::Small || - (CM == CodeModel::Medium && (Global || - Reason != DwarfEncoding::Data))) - Format = DW_EH_PE_sdata4; - else - Format = DW_EH_PE_sdata8; - } - - if (Global) - Format |= DW_EH_PE_indirect; - - return (Format | DW_EH_PE_pcrel); - } else { - if (is64Bit && - (CM == CodeModel::Small || - (CM == CodeModel::Medium && Reason != DwarfEncoding::Data))) - return DW_EH_PE_udata4; - else - return DW_EH_PE_absptr; - } -} - -X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM): - X86GenericTargetAsmInfo(TM) { - - GlobalPrefix = "_"; - LCOMMDirective = "\t.lcomm\t"; - COMMDirectiveTakesAlignment = false; - HasDotTypeDotSizeDirective = false; - HasSingleParameterDotFile = false; - StaticCtorsSection = "\t.section .ctors,\"aw\""; - StaticDtorsSection = "\t.section .dtors,\"aw\""; - HiddenDirective = NULL; - PrivateGlobalPrefix = "L"; // Prefix for private global symbols - WeakRefDirective = "\t.weak\t"; - SetDirective = "\t.set\t"; - - // Set up DWARF directives - HasLEB128 = true; // Target asm supports leb128 directives (little-endian) - AbsoluteDebugSectionOffsets = true; - AbsoluteEHSectionOffsets = false; - SupportsDebugInformation = true; - DwarfSectionOffsetDirective = "\t.secrel32\t"; - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"dr\""; - DwarfInfoSection = "\t.section\t.debug_info,\"dr\""; - DwarfLineSection = "\t.section\t.debug_line,\"dr\""; - DwarfFrameSection = "\t.section\t.debug_frame,\"dr\""; - DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\""; - DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\""; - DwarfStrSection = "\t.section\t.debug_str,\"dr\""; - DwarfLocSection = "\t.section\t.debug_loc,\"dr\""; - DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\""; - DwarfRangesSection = "\t.section\t.debug_ranges,\"dr\""; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"dr\""; -} - -unsigned -X86COFFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const { - CodeModel::Model CM = TM.getCodeModel(); - bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit(); - - if (TM.getRelocationModel() == Reloc::PIC_) { - unsigned Format = 0; - - if (!is64Bit) - // 32 bit targets always encode pointers as 4 bytes - Format = DW_EH_PE_sdata4; - else { - // 64 bit targets encode pointers in 4 bytes iff: - // - code model is small OR - // - code model is medium and we're emitting externally visible symbols - // or any code symbols - if (CM == CodeModel::Small || - (CM == CodeModel::Medium && (Global || - Reason != DwarfEncoding::Data))) - Format = DW_EH_PE_sdata4; - else - Format = DW_EH_PE_sdata8; - } - - if (Global) - Format |= DW_EH_PE_indirect; - - return (Format | DW_EH_PE_pcrel); - } else { - if (is64Bit && - (CM == CodeModel::Small || - (CM == CodeModel::Medium && Reason != DwarfEncoding::Data))) - return DW_EH_PE_udata4; - else - return DW_EH_PE_absptr; - } -} - -std::string -X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, - SectionKind::Kind kind) const { - switch (kind) { - case SectionKind::Text: - return ".text$linkonce" + GV->getName(); - case SectionKind::Data: - case SectionKind::BSS: - case SectionKind::ThreadData: - case SectionKind::ThreadBSS: - return ".data$linkonce" + GV->getName(); - case SectionKind::ROData: - case SectionKind::RODataMergeConst: - case SectionKind::RODataMergeStr: - return ".rdata$linkonce" + GV->getName(); - default: - assert(0 && "Unknown section kind"); - } - return NULL; -} - -std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const { - std::string Flags = ",\""; - - if (flags & SectionFlags::Code) - Flags += 'x'; - if (flags & SectionFlags::Writeable) - Flags += 'w'; - - Flags += "\""; - - return Flags; -} - -X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM): - X86GenericTargetAsmInfo(TM) { - GlobalPrefix = "_"; - CommentString = ";"; - - InlineAsmStart = "; InlineAsm Start"; - InlineAsmEnd = "; InlineAsm End"; - - PrivateGlobalPrefix = "$"; - AlignDirective = "\tALIGN\t"; - ZeroDirective = "\tdb\t"; - ZeroDirectiveSuffix = " dup(0)"; - AsciiDirective = "\tdb\t"; - AscizDirective = 0; - Data8bitsDirective = "\tdb\t"; - Data16bitsDirective = "\tdw\t"; - Data32bitsDirective = "\tdd\t"; - Data64bitsDirective = "\tdq\t"; - HasDotTypeDotSizeDirective = false; - HasSingleParameterDotFile = false; - - AlignmentIsInBytes = true; - - TextSection = getUnnamedSection("_text", SectionFlags::Code); - DataSection = getUnnamedSection("_data", SectionFlags::Writeable); - - JumpTableDataSection = NULL; - SwitchToSectionDirective = ""; - TextSectionStartSuffix = "\tSEGMENT PARA 'CODE'"; - DataSectionStartSuffix = "\tSEGMENT PARA 'DATA'"; - SectionEndDirectiveSuffix = "\tends\n"; -} - -template <class BaseTAI> -bool X86TargetAsmInfo<BaseTAI>::LowerToBSwap(CallInst *CI) const { - // FIXME: this should verify that we are targetting a 486 or better. If not, - // we will turn this bswap into something that will be lowered to logical ops - // instead of emitting the bswap asm. For now, we don't support 486 or lower - // so don't worry about this. - - // Verify this is a simple bswap. - if (CI->getNumOperands() != 2 || - CI->getType() != CI->getOperand(1)->getType() || - !CI->getType()->isInteger()) - return false; - - const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); - if (!Ty || Ty->getBitWidth() % 16 != 0) - return false; - - // Okay, we can do this xform, do so now. - const Type *Tys[] = { Ty }; - Module *M = CI->getParent()->getParent()->getParent(); - Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1); - - Value *Op = CI->getOperand(1); - Op = CallInst::Create(Int, Op, CI->getName(), CI); - - CI->replaceAllUsesWith(Op); - CI->eraseFromParent(); - return true; -} - -template <class BaseTAI> -bool X86TargetAsmInfo<BaseTAI>::ExpandInlineAsm(CallInst *CI) const { - InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue()); - std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints(); - - std::string AsmStr = IA->getAsmString(); - - // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a" - std::vector<std::string> AsmPieces; - SplitString(AsmStr, AsmPieces, "\n"); // ; as separator? - - switch (AsmPieces.size()) { - default: return false; - case 1: - AsmStr = AsmPieces[0]; - AsmPieces.clear(); - SplitString(AsmStr, AsmPieces, " \t"); // Split with whitespace. - - // bswap $0 - if (AsmPieces.size() == 2 && - (AsmPieces[0] == "bswap" || - AsmPieces[0] == "bswapq" || - AsmPieces[0] == "bswapl") && - (AsmPieces[1] == "$0" || - AsmPieces[1] == "${0:q}")) { - // No need to check constraints, nothing other than the equivalent of - // "=r,0" would be valid here. - return LowerToBSwap(CI); - } - // rorw $$8, ${0:w} --> llvm.bswap.i16 - if (CI->getType() == Type::Int16Ty && - AsmPieces.size() == 3 && - AsmPieces[0] == "rorw" && - AsmPieces[1] == "$$8," && - AsmPieces[2] == "${0:w}" && - IA->getConstraintString() == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") { - return LowerToBSwap(CI); - } - break; - case 3: - if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 && - Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && - Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { - // bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64 - std::vector<std::string> Words; - SplitString(AsmPieces[0], Words, " \t"); - if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { - Words.clear(); - SplitString(AsmPieces[1], Words, " \t"); - if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") { - Words.clear(); - SplitString(AsmPieces[2], Words, " \t,"); - if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" && - Words[2] == "%edx") { - return LowerToBSwap(CI); - } - } - } - } - break; - } - return false; -} - -// Instantiate default implementation. -TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>); diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h deleted file mode 100644 index f89171d..0000000 --- a/lib/Target/X86/X86TargetAsmInfo.h +++ /dev/null @@ -1,75 +0,0 @@ -//=====-- X86TargetAsmInfo.h - X86 asm properties -------------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the X86TargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86TARGETASMINFO_H -#define X86TARGETASMINFO_H - -#include "X86TargetMachine.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/ELFTargetAsmInfo.h" -#include "llvm/Target/DarwinTargetAsmInfo.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - - extern const char *const x86_asm_table[]; - - template <class BaseTAI> - struct X86TargetAsmInfo : public BaseTAI { - explicit X86TargetAsmInfo(const X86TargetMachine &TM): - BaseTAI(TM) { - const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>(); - - BaseTAI::AsmTransCBE = x86_asm_table; - BaseTAI::AssemblerDialect = Subtarget->getAsmFlavor(); - } - - virtual bool ExpandInlineAsm(CallInst *CI) const; - - private: - bool LowerToBSwap(CallInst *CI) const; - }; - - typedef X86TargetAsmInfo<TargetAsmInfo> X86GenericTargetAsmInfo; - - EXTERN_TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>); - - struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo<DarwinTargetAsmInfo> { - explicit X86DarwinTargetAsmInfo(const X86TargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - virtual const char *getEHGlobalPrefix() const; - }; - - struct X86ELFTargetAsmInfo : public X86TargetAsmInfo<ELFTargetAsmInfo> { - explicit X86ELFTargetAsmInfo(const X86TargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - }; - - struct X86COFFTargetAsmInfo : public X86GenericTargetAsmInfo { - explicit X86COFFTargetAsmInfo(const X86TargetMachine &TM); - virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, - bool Global) const; - virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, - SectionKind::Kind kind) const; - virtual std::string printSectionFlags(unsigned flags) const; - }; - - struct X86WinTargetAsmInfo : public X86GenericTargetAsmInfo { - explicit X86WinTargetAsmInfo(const X86TargetMachine &TM); - }; - -} // namespace llvm - -#endif diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp deleted file mode 100644 index 67cb0c8..0000000 --- a/lib/Target/XCore/XCoreAsmPrinter.cpp +++ /dev/null @@ -1,438 +0,0 @@ -//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===// -// -// 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 the XAS-format XCore assembly language. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "XCore.h" -#include "XCoreInstrInfo.h" -#include "XCoreSubtarget.h" -#include "XCoreTargetMachine.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Support/Mangler.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <cctype> -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -static cl::opt<std::string> FileDirective("xcore-file-directive", cl::Optional, - cl::desc("Output a file directive into the assembly file"), - cl::Hidden, - cl::value_desc("filename"), - cl::init("")); - -static cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional, - cl::desc("Maximum number of threads (for emulation thread-local storage)"), - cl::Hidden, - cl::value_desc("number"), - cl::init(8)); - -namespace { - class VISIBILITY_HIDDEN XCoreAsmPrinter : public AsmPrinter { - DwarfWriter *DW; - const XCoreSubtarget &Subtarget; - public: - explicit XCoreAsmPrinter(raw_ostream &O, XCoreTargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V), DW(0), - Subtarget(*TM.getSubtargetImpl()) {} - - virtual const char *getPassName() const { - return "XCore Assembly Printer"; - } - - void printMemOperand(const MachineInstr *MI, int opNum); - void printOperand(const MachineInstr *MI, int opNum); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - - void emitFileDirective(const std::string &filename); - void emitGlobalDirective(const std::string &name); - void emitExternDirective(const std::string &name); - - void emitArrayBound(const std::string &name, const GlobalVariable *GV); - void emitGlobal(const GlobalVariable *GV); - - void emitFunctionStart(MachineFunction &MF); - void emitFunctionEnd(MachineFunction &MF); - - bool printInstruction(const MachineInstr *MI); // autogenerated. - void printMachineInstruction(const MachineInstr *MI); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - void getAnalysisUsage(AnalysisUsage &AU) const { - AsmPrinter::getAnalysisUsage(AU); - AU.setPreservesAll(); - AU.addRequired<MachineModuleInfo>(); - AU.addRequired<DwarfWriter>(); - } - }; -} // end of anonymous namespace - -#include "XCoreGenAsmWriter.inc" - -/// createXCoreCodePrinterPass - Returns a pass that prints the XCore -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createXCoreCodePrinterPass(raw_ostream &o, - XCoreTargetMachine &tm, - bool verbose) { - return new XCoreAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); -} - -// PrintEscapedString - Print each character of the specified string, escaping -// it if it is not printable or if it is an escape char. -static void PrintEscapedString(const std::string &Str, raw_ostream &Out) { - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - unsigned char C = Str[i]; - if (isprint(C) && C != '"' && C != '\\') { - Out << C; - } else { - Out << '\\' - << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')) - << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); - } - } -} - -void XCoreAsmPrinter:: -emitFileDirective(const std::string &name) -{ - O << "\t.file\t\""; - PrintEscapedString(name, O); - O << "\"\n"; -} - -void XCoreAsmPrinter:: -emitGlobalDirective(const std::string &name) -{ - O << TAI->getGlobalDirective() << name; - O << "\n"; -} - -void XCoreAsmPrinter:: -emitExternDirective(const std::string &name) -{ - O << "\t.extern\t" << name; - O << '\n'; -} - -void XCoreAsmPrinter:: -emitArrayBound(const std::string &name, const GlobalVariable *GV) -{ - assert(((GV->hasExternalLinkage() || - GV->hasWeakLinkage()) || - GV->hasLinkOnceLinkage()) && "Unexpected linkage"); - if (const ArrayType *ATy = dyn_cast<ArrayType>( - cast<PointerType>(GV->getType())->getElementType())) - { - O << TAI->getGlobalDirective() << name << ".globound" << "\n"; - O << TAI->getSetDirective() << name << ".globound" << "," - << ATy->getNumElements() << "\n"; - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { - // TODO Use COMDAT groups for LinkOnceLinkage - O << TAI->getWeakDefDirective() << name << ".globound" << "\n"; - } - } -} - -void XCoreAsmPrinter:: -emitGlobal(const GlobalVariable *GV) -{ - const TargetData *TD = TM.getTargetData(); - - if (GV->hasInitializer()) { - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(GV)) - return; - - SwitchToSection(TAI->SectionForGlobal(GV)); - - std::string name = Mang->getValueName(GV); - Constant *C = GV->getInitializer(); - unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); - - // Mark the start of the global - O << "\t.cc_top " << name << ".data," << name << "\n"; - - switch (GV->getLinkage()) { - case GlobalValue::AppendingLinkage: - cerr << "AppendingLinkage is not supported by this target!\n"; - abort(); - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - case GlobalValue::ExternalLinkage: - emitArrayBound(name, GV); - emitGlobalDirective(name); - // TODO Use COMDAT groups for LinkOnceLinkage - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { - O << TAI->getWeakDefDirective() << name << "\n"; - } - // FALL THROUGH - case GlobalValue::InternalLinkage: - case GlobalValue::PrivateLinkage: - break; - case GlobalValue::GhostLinkage: - cerr << "Should not have any unmaterialized functions!\n"; - abort(); - case GlobalValue::DLLImportLinkage: - cerr << "DLLImport linkage is not supported by this target!\n"; - abort(); - case GlobalValue::DLLExportLinkage: - cerr << "DLLExport linkage is not supported by this target!\n"; - abort(); - default: - assert(0 && "Unknown linkage type!"); - } - - EmitAlignment(Align, GV, 2); - - unsigned Size = TD->getTypeAllocSize(C->getType()); - if (GV->isThreadLocal()) { - Size *= MaxThreads; - } - if (TAI->hasDotTypeDotSizeDirective()) { - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; - } - O << name << ":\n"; - - EmitGlobalConstant(C); - if (GV->isThreadLocal()) { - for (unsigned i = 1; i < MaxThreads; ++i) { - EmitGlobalConstant(C); - } - } - if (Size < 4) { - // The ABI requires that unsigned scalar types smaller than 32 bits - // are are padded to 32 bits. - EmitZeros(4 - Size); - } - - // Mark the end of the global - O << "\t.cc_bottom " << name << ".data\n"; - } -} - -/// Emit the directives on the start of functions -void XCoreAsmPrinter:: -emitFunctionStart(MachineFunction &MF) -{ - // Print out the label for the function. - const Function *F = MF.getFunction(); - - SwitchToSection(TAI->SectionForGlobal(F)); - - // Mark the start of the function - O << "\t.cc_top " << CurrentFnName << ".function," << CurrentFnName << "\n"; - - switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); - case Function::InternalLinkage: // Symbols default to internal. - case Function::PrivateLinkage: - break; - case Function::ExternalLinkage: - emitGlobalDirective(CurrentFnName); - break; - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: - // TODO Use COMDAT groups for LinkOnceLinkage - O << TAI->getGlobalDirective() << CurrentFnName << "\n"; - O << TAI->getWeakDefDirective() << CurrentFnName << "\n"; - break; - } - // (1 << 1) byte aligned - EmitAlignment(MF.getAlignment(), F, 1); - if (TAI->hasDotTypeDotSizeDirective()) { - O << "\t.type " << CurrentFnName << ",@function\n"; - } - O << CurrentFnName << ":\n"; -} - -/// Emit the directives on the end of functions -void XCoreAsmPrinter:: -emitFunctionEnd(MachineFunction &MF) -{ - // Mark the end of the function - O << "\t.cc_bottom " << CurrentFnName << ".function\n"; -} - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF) -{ - this->MF = &MF; - - SetupMachineFunction(MF); - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - // Print out jump tables referenced by the function - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - - // Emit the function start directives - emitFunctionStart(MF); - - // Emit pre-function debug information. - DW->BeginFunction(&MF); - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - - // Print a label for the basic block. - if (I != MF.begin()) { - printBasicBlockLabel(I, true , true); - O << '\n'; - } - - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - O << "\t"; - printMachineInstruction(II); - } - - // Each Basic Block is separated by a newline - O << '\n'; - } - - // Emit function end directives - emitFunctionEnd(MF); - - // Emit post-function debug information. - DW->EndFunction(&MF); - - // We didn't modify anything. - return false; -} - -void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) -{ - printOperand(MI, opNum); - - if (MI->getOperand(opNum+1).isImm() - && MI->getOperand(opNum+1).getImm() == 0) - return; - - O << "+"; - printOperand(MI, opNum+1); -} - -void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { - const MachineOperand &MO = MI->getOperand(opNum); - switch (MO.getType()) { - case MachineOperand::MO_Register: - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) - O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; - else - assert(0 && "not implemented"); - break; - case MachineOperand::MO_Immediate: - O << MO.getImm(); - break; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - break; - case MachineOperand::MO_GlobalAddress: - O << Mang->getValueName(MO.getGlobal()); - break; - case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); - break; - case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - default: - assert(0 && "not implemented"); - } -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - printOperand(MI, OpNo); - return false; -} - -void XCoreAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - // Check for mov mnemonic - unsigned src, dst, srcSR, dstSR; - if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) { - O << "\tmov "; - O << TM.getRegisterInfo()->get(dst).AsmName; - O << ", "; - O << TM.getRegisterInfo()->get(src).AsmName; - O << "\n"; - return; - } - if (printInstruction(MI)) { - return; - } - assert(0 && "Unhandled instruction in asm writer!"); -} - -bool XCoreAsmPrinter::doInitialization(Module &M) { - bool Result = AsmPrinter::doInitialization(M); - DW = getAnalysisIfAvailable<DwarfWriter>(); - - if (!FileDirective.empty()) - emitFileDirective(FileDirective); - - return Result; -} - -bool XCoreAsmPrinter::doFinalization(Module &M) { - - // Print out module-level global variables. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - emitGlobal(I); - } - - return AsmPrinter::doFinalization(M); -} diff --git a/lib/Target/XCore/XCoreTargetAsmInfo.cpp b/lib/Target/XCore/XCoreTargetAsmInfo.cpp deleted file mode 100644 index 59ad624..0000000 --- a/lib/Target/XCore/XCoreTargetAsmInfo.cpp +++ /dev/null @@ -1,202 +0,0 @@ -//===-- XCoreTargetAsmInfo.cpp - XCore asm properties -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declarations of the XCoreTargetAsmInfo properties. -// We use the small section flag for the CP relative and DP relative -// flags. If a section is small and writable then it is DP relative. If a -// section is small and not writable then it is CP relative. -// -//===----------------------------------------------------------------------===// - -#include "XCoreTargetAsmInfo.h" -#include "XCoreTargetMachine.h" -#include "llvm/GlobalVariable.h" -#include "llvm/ADT/StringExtras.h" - -using namespace llvm; - -XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM) - : ELFTargetAsmInfo(TM), - Subtarget(TM.getSubtargetImpl()) { - SupportsDebugInformation = true; - TextSection = getUnnamedSection("\t.text", SectionFlags::Code); - DataSection = getNamedSection("\t.dp.data", SectionFlags::Writeable | - SectionFlags::Small); - BSSSection_ = getNamedSection("\t.dp.bss", SectionFlags::Writeable | - SectionFlags::BSS | SectionFlags::Small); - if (Subtarget->isXS1A()) { - ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::None | - SectionFlags::Writeable | - SectionFlags::Small); - } else { - ReadOnlySection = getNamedSection("\t.cp.rodata", SectionFlags::None | - SectionFlags::Small); - } - Data16bitsDirective = "\t.short\t"; - Data32bitsDirective = "\t.long\t"; - Data64bitsDirective = 0; - ZeroDirective = "\t.space\t"; - CommentString = "#"; - ConstantPoolSection = "\t.section\t.cp.rodata,\"ac\",@progbits"; - JumpTableDataSection = "\t.section\t.dp.data,\"awd\",@progbits"; - PrivateGlobalPrefix = ".L"; - AscizDirective = ".asciiz"; - WeakDefDirective = "\t.weak\t"; - WeakRefDirective = "\t.weak\t"; - SetDirective = "\t.set\t"; - - // Debug - HasLEB128 = true; - AbsoluteDebugSectionOffsets = true; - - DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits"; - DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits"; - DwarfLineSection = "\t.section\t.debug_line,\"\",@progbits"; - DwarfFrameSection = "\t.section\t.debug_frame,\"\",@progbits"; - DwarfPubNamesSection = "\t.section\t.debug_pubnames,\"\",@progbits"; - DwarfPubTypesSection = "\t.section\t.debug_pubtypes,\"\",@progbits"; - DwarfStrSection = "\t.section\t.debug_str,\"\",@progbits"; - DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; - DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; - DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; - DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; -} - -const Section* -XCoreTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { - SectionKind::Kind Kind = SectionKindForGlobal(GV); - - if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) - { - if (!GVar->isWeakForLinker()) { - switch (Kind) { - case SectionKind::RODataMergeStr: - return MergeableStringSection(GVar); - case SectionKind::RODataMergeConst: - return getReadOnlySection(); - case SectionKind::ThreadData: - return DataSection; - case SectionKind::ThreadBSS: - return getBSSSection_(); - default: - break; - } - } - } - return ELFTargetAsmInfo::SelectSectionForGlobal(GV); -} - -const Section* -XCoreTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { - return MergeableConstSection(Ty); -} - -const Section* -XCoreTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { - Constant *C = GV->getInitializer(); - return MergeableConstSection(C->getType()); -} - -inline const Section* -XCoreTargetAsmInfo::MergeableConstSection(const Type *Ty) const { - const TargetData *TD = TM.getTargetData(); - - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size == 4 || Size == 8 || Size == 16) { - std::string Name = ".cp.const" + utostr(Size); - - return getNamedSection(Name.c_str(), - SectionFlags::setEntitySize(SectionFlags::Mergeable | - SectionFlags::Small, - Size)); - } - - return getReadOnlySection(); -} - -const Section* XCoreTargetAsmInfo:: -MergeableStringSection(const GlobalVariable *GV) const { - // FIXME insert in correct mergable section - return getReadOnlySection(); -} - -unsigned XCoreTargetAsmInfo:: -SectionFlagsForGlobal(const GlobalValue *GV, - const char* Name) const { - unsigned Flags = ELFTargetAsmInfo::SectionFlagsForGlobal(GV, Name); - // Mask out unsupported flags - Flags &= ~(SectionFlags::Small | SectionFlags::TLS); - - // Set CP / DP relative flags - if (GV) { - SectionKind::Kind Kind = SectionKindForGlobal(GV); - switch (Kind) { - case SectionKind::ThreadData: - case SectionKind::ThreadBSS: - case SectionKind::Data: - case SectionKind::BSS: - case SectionKind::SmallData: - case SectionKind::SmallBSS: - Flags |= SectionFlags::Small; - break; - case SectionKind::ROData: - case SectionKind::RODataMergeStr: - case SectionKind::SmallROData: - if (Subtarget->isXS1A()) { - Flags |= SectionFlags::Writeable; - } - Flags |=SectionFlags::Small; - break; - case SectionKind::RODataMergeConst: - Flags |=SectionFlags::Small; - default: - break; - } - } - - return Flags; -} - -std::string XCoreTargetAsmInfo:: -printSectionFlags(unsigned flags) const { - std::string Flags = ",\""; - - if (!(flags & SectionFlags::Debug)) - Flags += 'a'; - if (flags & SectionFlags::Code) - Flags += 'x'; - if (flags & SectionFlags::Writeable) - Flags += 'w'; - if (flags & SectionFlags::Mergeable) - Flags += 'M'; - if (flags & SectionFlags::Strings) - Flags += 'S'; - if (flags & SectionFlags::TLS) - Flags += 'T'; - if (flags & SectionFlags::Small) { - if (flags & SectionFlags::Writeable) - Flags += 'd'; // DP relative - else - Flags += 'c'; // CP relative - } - - Flags += "\","; - - Flags += '@'; - - if (flags & SectionFlags::BSS) - Flags += "nobits"; - else - Flags += "progbits"; - - if (unsigned entitySize = SectionFlags::getEntitySize(flags)) - Flags += "," + utostr(entitySize); - - return Flags; -} diff --git a/lib/Target/XCore/XCoreTargetAsmInfo.h b/lib/Target/XCore/XCoreTargetAsmInfo.h deleted file mode 100644 index 79fd36a..0000000 --- a/lib/Target/XCore/XCoreTargetAsmInfo.h +++ /dev/null @@ -1,45 +0,0 @@ -//=====-- XCoreTargetAsmInfo.h - XCore asm properties ---------*- C++ -*--====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the XCoreTargetAsmInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef XCORETARGETASMINFO_H -#define XCORETARGETASMINFO_H - -#include "llvm/Target/ELFTargetAsmInfo.h" - -namespace llvm { - - // Forward declarations. - class XCoreTargetMachine; - class XCoreSubtarget; - - class XCoreTargetAsmInfo : public ELFTargetAsmInfo { - private: - const XCoreSubtarget *Subtarget; - public: - explicit XCoreTargetAsmInfo(const XCoreTargetMachine &TM); - - virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; - virtual std::string printSectionFlags(unsigned flags) const; - const Section* MergeableConstSection(const GlobalVariable *GV) const; - inline const Section* MergeableConstSection(const Type *Ty) const; - const Section* MergeableStringSection(const GlobalVariable *GV) const; - virtual const Section* - SelectSectionForMachineConst(const Type *Ty) const; - virtual unsigned - SectionFlagsForGlobal(const GlobalValue *GV = NULL, - const char* name = NULL) const; - }; - -} // namespace llvm - -#endif |