#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"
using namespace llvm;
Data64bitsDirective = 0; // we can't emit a 64-bit unit
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
+ BSSSection = 0; // no BSS section.
+ ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill
ConstantPoolSection = "\t.const\n";
JumpTableDataSection = "\t.const\n";
CStringSection = "\t.cstring";
EightByteConstantSection = "\t.literal8\n";
if (Subtarget->is64Bit())
SixteenByteConstantSection = "\t.literal16\n";
+ ReadOnlySection = "\t.const\n";
LCOMMDirective = "\t.lcomm\t";
COMMDirectiveTakesAlignment = false;
HasDotTypeDotSizeDirective = false;
- StaticCtorsSection = ".mod_init_func";
- StaticDtorsSection = ".mod_term_func";
+ if (TM.getRelocationModel() == Reloc::Static) {
+ StaticCtorsSection = ".constructor";
+ StaticDtorsSection = ".destructor";
+ } else {
+ StaticCtorsSection = ".mod_init_func";
+ StaticDtorsSection = ".mod_term_func";
+ }
InlineAsmStart = "# InlineAsm Start";
InlineAsmEnd = "# InlineAsm End";
SetDirective = "\t.set";
UsedDirective = "\t.no_dead_strip\t";
+ WeakRefDirective = "\t.weak_reference\t";
+ HiddenDirective = "\t.private_extern\t";
+
+ // In non-PIC modes, emit a special label before jump tables so that the
+ // linker can perform more accurate dead code stripping.
+ if (TM.getRelocationModel() != Reloc::PIC_) {
+ // Emit a local label that is preserved until the linker runs.
+ JumpTableSpecialLabelPrefix = "l";
+ }
NeedsSet = true;
DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
case X86Subtarget::isELF:
// Set up DWARF directives
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
+ AbsoluteSectionOffsets = true;
// bool HasLEB128; // Defaults to false.
// hasDotLoc - True if target asm supports .loc directives.
// bool HasDotLoc; // Defaults to false.
// HasDotFile - True if target asm supports .file directives.
// bool HasDotFile; // Defaults to false.
- PrivateGlobalPrefix = "."; // Prefix for private global symbols
+ ReadOnlySection = "\t.section\t.rodata\n";
+ PrivateGlobalPrefix = ".L";
+ WeakRefDirective = "\t.weak\t";
DwarfRequiresFrameSection = false;
DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits";
DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits";
break;
case X86Subtarget::isCygwin:
+ case X86Subtarget::isMingw:
GlobalPrefix = "_";
+ LCOMMDirective = "\t.lcomm\t";
COMMDirectiveTakesAlignment = false;
HasDotTypeDotSizeDirective = false;
StaticCtorsSection = "\t.section .ctors,\"aw\"";
StaticDtorsSection = "\t.section .dtors,\"aw\"";
+ HiddenDirective = NULL;
// Set up DWARF directives
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
+ AbsoluteSectionOffsets = true;
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
+ WeakRefDirective = "\t.weak\t";
DwarfRequiresFrameSection = false;
+ 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\"";
DwarfRangesSection = "\t.section\t.debug_ranges,\"dr\"";
DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
break;
-
- break;
+
case X86Subtarget::isWindows:
GlobalPrefix = "_";
HasDotTypeDotSizeDirective = false;
break;
+
default: break;
}
TextSection = "_text";
DataSection = "_data";
+ JumpTableDataSection = NULL;
SwitchToSectionDirective = "";
TextSectionStartSuffix = "\tsegment 'CODE'";
DataSectionStartSuffix = "\tsegment 'DATA'";
SectionEndDirectiveSuffix = "\tends\n";
}
+
+ AssemblerDialect = Subtarget->getAsmFlavor();
}
bool X86TargetAsmInfo::LowerToBSwap(CallInst *CI) const {
!CI->getType()->isInteger())
return false;
- const Type *Ty = CI->getType()->getUnsignedVersion();
- const char *IntName;
- switch (Ty->getTypeID()) {
- default: return false;
- case Type::UShortTyID: IntName = "llvm.bswap.i16"; break;
- case Type::UIntTyID: IntName = "llvm.bswap.i32"; break;
- case Type::ULongTyID: IntName = "llvm.bswap.i64"; break;
- }
-
+ 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, Ty };
Module *M = CI->getParent()->getParent()->getParent();
- Function *Int = M->getOrInsertFunction(IntName, Ty, Ty, (Type*)0);
+ Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 2);
Value *Op = CI->getOperand(1);
- if (CI->getOperand(1)->getType() != Ty)
- Op = new BitCastInst(Op, Ty, Op->getName(), CI);
-
Op = new CallInst(Int, Op, CI->getName(), CI);
- if (Op->getType() != CI->getType())
- Op = new BitCastInst(Op, CI->getType(), Op->getName(), CI);
-
CI->replaceAllUsesWith(Op);
CI->eraseFromParent();
return true;
}
break;
case 3:
- if (CI->getType() == Type::ULongTy && Constraints.size() >= 2 &&
+ 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