| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 1 | //===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file was developed by James M. Laskey and is distributed under the | 
 | 6 | // University of Illinois Open Source License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This file contains the declarations of the X86TargetAsmInfo properties. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
 | 14 | #include "X86TargetAsmInfo.h" | 
 | 15 | #include "X86TargetMachine.h" | 
 | 16 | #include "X86Subtarget.h" | 
| Reid Spencer | 7aa8a45 | 2007-01-12 23:22:14 +0000 | [diff] [blame] | 17 | #include "llvm/DerivedTypes.h" | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 18 | #include "llvm/InlineAsm.h" | 
 | 19 | #include "llvm/Instructions.h" | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 20 | #include "llvm/Intrinsics.h" | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 21 | #include "llvm/Module.h" | 
 | 22 | #include "llvm/ADT/StringExtras.h" | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 23 | using namespace llvm; | 
 | 24 |  | 
| Andrew Lenharth | 6c0695f | 2006-11-28 19:52:49 +0000 | [diff] [blame] | 25 | static const char* x86_asm_table[] = {"{si}", "S", | 
 | 26 |                                       "{di}", "D", | 
 | 27 |                                       "{ax}", "a", | 
 | 28 |                                       "{cx}", "c", | 
| Andrew Lenharth | 6c0695f | 2006-11-28 19:52:49 +0000 | [diff] [blame] | 29 |                                       "{memory}", "memory", | 
 | 30 |                                       "{flags}", "", | 
 | 31 |                                       "{dirflag}", "", | 
 | 32 |                                       "{fpsr}", "", | 
 | 33 |                                       "{cc}", "cc", | 
 | 34 |                                       0,0}; | 
 | 35 |  | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 36 | X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) { | 
 | 37 |   const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>(); | 
 | 38 |    | 
| Chris Lattner | afbfded | 2006-10-05 02:43:52 +0000 | [diff] [blame] | 39 |   // FIXME - Should be simplified. | 
| Andrew Lenharth | 6c0695f | 2006-11-28 19:52:49 +0000 | [diff] [blame] | 40 |  | 
 | 41 |   AsmTransCBE = x86_asm_table; | 
 | 42 |    | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 43 |   switch (Subtarget->TargetType) { | 
 | 44 |   case X86Subtarget::isDarwin: | 
 | 45 |     AlignmentIsInBytes = false; | 
 | 46 |     GlobalPrefix = "_"; | 
| Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 47 |     if (!Subtarget->is64Bit()) | 
 | 48 |       Data64bitsDirective = 0;       // we can't emit a 64-bit unit | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 49 |     ZeroDirective = "\t.space\t";  // ".space N" emits N zeros. | 
 | 50 |     PrivateGlobalPrefix = "L";     // Marker for constant pool idxs | 
| Chris Lattner | 42ca450 | 2007-01-17 17:43:33 +0000 | [diff] [blame] | 51 |     BSSSection = 0;                       // no BSS section. | 
 | 52 |     ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 53 |     ConstantPoolSection = "\t.const\n"; | 
| Chris Lattner | afbfded | 2006-10-05 02:43:52 +0000 | [diff] [blame] | 54 |     JumpTableDataSection = "\t.const\n"; | 
| Evan Cheng | 8910c1c | 2006-10-26 19:18:18 +0000 | [diff] [blame] | 55 |     CStringSection = "\t.cstring"; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 56 |     FourByteConstantSection = "\t.literal4\n"; | 
 | 57 |     EightByteConstantSection = "\t.literal8\n"; | 
| Evan Cheng | 25ab690 | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 58 |     if (Subtarget->is64Bit()) | 
 | 59 |       SixteenByteConstantSection = "\t.literal16\n"; | 
| Evan Cheng | f0b5d56 | 2007-03-08 01:07:07 +0000 | [diff] [blame] | 60 |     ReadOnlySection = "\t.const\n"; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 61 |     LCOMMDirective = "\t.lcomm\t"; | 
 | 62 |     COMMDirectiveTakesAlignment = false; | 
 | 63 |     HasDotTypeDotSizeDirective = false; | 
| Evan Cheng | b267ca1 | 2007-01-30 08:04:53 +0000 | [diff] [blame] | 64 |     if (TM.getRelocationModel() == Reloc::Static) { | 
 | 65 |       StaticCtorsSection = ".constructor"; | 
 | 66 |       StaticDtorsSection = ".destructor"; | 
 | 67 |     } else { | 
 | 68 |       StaticCtorsSection = ".mod_init_func"; | 
 | 69 |       StaticDtorsSection = ".mod_term_func"; | 
 | 70 |     } | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 71 |     InlineAsmStart = "# InlineAsm Start"; | 
 | 72 |     InlineAsmEnd = "# InlineAsm End"; | 
 | 73 |     SetDirective = "\t.set"; | 
| Chris Lattner | a53115b | 2006-09-26 03:39:53 +0000 | [diff] [blame] | 74 |     UsedDirective = "\t.no_dead_strip\t"; | 
| Evan Cheng | 8752ce6 | 2006-12-01 20:47:11 +0000 | [diff] [blame] | 75 |     WeakRefDirective = "\t.weak_reference\t"; | 
| Chris Lattner | 43bbc5c | 2007-01-14 06:29:53 +0000 | [diff] [blame] | 76 |     HiddenDirective = "\t.private_extern\t"; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 77 |      | 
| Chris Lattner | b266ccd | 2007-01-18 01:15:58 +0000 | [diff] [blame] | 78 |     // In non-PIC modes, emit a special label before jump tables so that the | 
 | 79 |     // linker can perform more accurate dead code stripping. | 
 | 80 |     if (TM.getRelocationModel() != Reloc::PIC_) { | 
 | 81 |       // Emit a local label that is preserved until the linker runs. | 
 | 82 |       JumpTableSpecialLabelPrefix = "l"; | 
 | 83 |     } | 
| Anton Korobeynikov | 2a07e2f | 2007-05-05 09:04:50 +0000 | [diff] [blame] | 84 |  | 
 | 85 |     SupportsDebugInformation = true; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 86 |     NeedsSet = true; | 
 | 87 |     DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; | 
 | 88 |     DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; | 
 | 89 |     DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; | 
 | 90 |     DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; | 
 | 91 |     DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; | 
 | 92 |     DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; | 
 | 93 |     DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; | 
 | 94 |     DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; | 
 | 95 |     DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; | 
 | 96 |     DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; | 
 | 97 |     DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; | 
 | 98 |     break; | 
| Reid Spencer | 02b8511 | 2006-10-30 22:32:30 +0000 | [diff] [blame] | 99 |  | 
 | 100 |   case X86Subtarget::isELF: | 
| Dan Gohman | 6445f61 | 2007-06-27 15:09:47 +0000 | [diff] [blame] | 101 |     ReadOnlySection = "\t.section\t.rodata"; | 
| Dan Gohman | 6f858e2 | 2007-05-03 16:38:57 +0000 | [diff] [blame] | 102 |     FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4"; | 
 | 103 |     EightByteConstantSection = "\t.section\t.rodata.cst8,\"aM\",@progbits,8"; | 
| Anton Korobeynikov | 2a07e2f | 2007-05-05 09:04:50 +0000 | [diff] [blame] | 104 |     SixteenByteConstantSection = "\t.section\t.rodata.cst16,\"aM\",@progbits,16"; | 
| Dan Gohman | 6f858e2 | 2007-05-03 16:38:57 +0000 | [diff] [blame] | 105 |     CStringSection = "\t.section\t.rodata.str1.1,\"aMS\",@progbits,1"; | 
| Chris Lattner | a3bfdd4 | 2007-01-03 18:16:48 +0000 | [diff] [blame] | 106 |     PrivateGlobalPrefix = ".L"; | 
| Evan Cheng | 8752ce6 | 2006-12-01 20:47:11 +0000 | [diff] [blame] | 107 |     WeakRefDirective = "\t.weak\t"; | 
| Anton Korobeynikov | 8b0a8c8 | 2007-04-25 14:27:10 +0000 | [diff] [blame] | 108 |     SetDirective = "\t.set\t"; | 
| Anton Korobeynikov | edb4a6b | 2007-05-01 10:19:31 +0000 | [diff] [blame] | 109 |     PCSymbol = "."; | 
| Anton Korobeynikov | 2a07e2f | 2007-05-05 09:04:50 +0000 | [diff] [blame] | 110 |  | 
 | 111 |     // Set up DWARF directives | 
 | 112 |     HasLEB128 = true;  // Target asm supports leb128 directives (little-endian) | 
 | 113 |     AbsoluteDebugSectionOffsets = true; | 
 | 114 |     AbsoluteEHSectionOffsets = false; | 
 | 115 |     SupportsDebugInformation = true; | 
| Reid Spencer | 02b8511 | 2006-10-30 22:32:30 +0000 | [diff] [blame] | 116 |     DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits"; | 
 | 117 |     DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits"; | 
 | 118 |     DwarfLineSection =    "\t.section\t.debug_line,\"\",@progbits"; | 
 | 119 |     DwarfFrameSection =   "\t.section\t.debug_frame,\"\",@progbits"; | 
 | 120 |     DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits"; | 
 | 121 |     DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits"; | 
 | 122 |     DwarfStrSection =     "\t.section\t.debug_str,\"\",@progbits"; | 
 | 123 |     DwarfLocSection =     "\t.section\t.debug_loc,\"\",@progbits"; | 
 | 124 |     DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; | 
 | 125 |     DwarfRangesSection =  "\t.section\t.debug_ranges,\"\",@progbits"; | 
 | 126 |     DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; | 
| Anton Korobeynikov | 2365f51 | 2007-07-14 14:06:15 +0000 | [diff] [blame] | 127 |  | 
 | 128 |     if (!Subtarget->is64Bit()) | 
 | 129 |       SupportsExceptionHandling = true; | 
| Anton Korobeynikov | 71144d8 | 2007-05-01 10:16:06 +0000 | [diff] [blame] | 130 |     DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits"; | 
 | 131 |     DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits"; | 
| Reid Spencer | 02b8511 | 2006-10-30 22:32:30 +0000 | [diff] [blame] | 132 |     break; | 
 | 133 |  | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 134 |   case X86Subtarget::isCygwin: | 
| Anton Korobeynikov | 317848f | 2007-01-03 11:43:14 +0000 | [diff] [blame] | 135 |   case X86Subtarget::isMingw: | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 136 |     GlobalPrefix = "_"; | 
| Anton Korobeynikov | 317848f | 2007-01-03 11:43:14 +0000 | [diff] [blame] | 137 |     LCOMMDirective = "\t.lcomm\t"; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 138 |     COMMDirectiveTakesAlignment = false; | 
 | 139 |     HasDotTypeDotSizeDirective = false; | 
 | 140 |     StaticCtorsSection = "\t.section .ctors,\"aw\""; | 
 | 141 |     StaticDtorsSection = "\t.section .dtors,\"aw\""; | 
| Anton Korobeynikov | 1a85645 | 2007-01-14 11:49:39 +0000 | [diff] [blame] | 142 |     HiddenDirective = NULL; | 
| Anton Korobeynikov | 2a07e2f | 2007-05-05 09:04:50 +0000 | [diff] [blame] | 143 |     PrivateGlobalPrefix = "L";  // Prefix for private global symbols | 
 | 144 |     WeakRefDirective = "\t.weak\t"; | 
 | 145 |     SetDirective = "\t.set\t"; | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 146 |  | 
 | 147 |     // Set up DWARF directives | 
 | 148 |     HasLEB128 = true;  // Target asm supports leb128 directives (little-endian) | 
| Anton Korobeynikov | 79dda2b | 2007-05-01 22:23:12 +0000 | [diff] [blame] | 149 |     AbsoluteDebugSectionOffsets = true; | 
 | 150 |     AbsoluteEHSectionOffsets = false; | 
| Anton Korobeynikov | 2a07e2f | 2007-05-05 09:04:50 +0000 | [diff] [blame] | 151 |     SupportsDebugInformation = true; | 
| Anton Korobeynikov | a6199c8 | 2007-03-07 02:47:57 +0000 | [diff] [blame] | 152 |     DwarfSectionOffsetDirective = "\t.secrel32\t"; | 
| Anton Korobeynikov | ab4022f | 2006-10-31 08:31:24 +0000 | [diff] [blame] | 153 |     DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\""; | 
 | 154 |     DwarfInfoSection =    "\t.section\t.debug_info,\"dr\""; | 
 | 155 |     DwarfLineSection =    "\t.section\t.debug_line,\"dr\""; | 
 | 156 |     DwarfFrameSection =   "\t.section\t.debug_frame,\"dr\""; | 
 | 157 |     DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\""; | 
 | 158 |     DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\""; | 
 | 159 |     DwarfStrSection =     "\t.section\t.debug_str,\"dr\""; | 
 | 160 |     DwarfLocSection =     "\t.section\t.debug_loc,\"dr\""; | 
 | 161 |     DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\""; | 
 | 162 |     DwarfRangesSection =  "\t.section\t.debug_ranges,\"dr\""; | 
 | 163 |     DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\""; | 
 | 164 |     break; | 
| Bill Wendling | 1150286 | 2007-01-16 04:13:03 +0000 | [diff] [blame] | 165 |  | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 166 |   case X86Subtarget::isWindows: | 
 | 167 |     GlobalPrefix = "_"; | 
 | 168 |     HasDotTypeDotSizeDirective = false; | 
 | 169 |     break; | 
| Bill Wendling | 1150286 | 2007-01-16 04:13:03 +0000 | [diff] [blame] | 170 |  | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 171 |   default: break; | 
 | 172 |   } | 
 | 173 |    | 
 | 174 |   if (Subtarget->isFlavorIntel()) { | 
 | 175 |     GlobalPrefix = "_"; | 
 | 176 |     CommentString = ";"; | 
 | 177 |    | 
 | 178 |     PrivateGlobalPrefix = "$"; | 
 | 179 |     AlignDirective = "\talign\t"; | 
 | 180 |     ZeroDirective = "\tdb\t"; | 
 | 181 |     ZeroDirectiveSuffix = " dup(0)"; | 
 | 182 |     AsciiDirective = "\tdb\t"; | 
 | 183 |     AscizDirective = 0; | 
 | 184 |     Data8bitsDirective = "\tdb\t"; | 
 | 185 |     Data16bitsDirective = "\tdw\t"; | 
 | 186 |     Data32bitsDirective = "\tdd\t"; | 
 | 187 |     Data64bitsDirective = "\tdq\t"; | 
 | 188 |     HasDotTypeDotSizeDirective = false; | 
 | 189 |      | 
 | 190 |     TextSection = "_text"; | 
 | 191 |     DataSection = "_data"; | 
| Anton Korobeynikov | 24287dd | 2006-12-19 21:04:20 +0000 | [diff] [blame] | 192 |     JumpTableDataSection = NULL; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 193 |     SwitchToSectionDirective = ""; | 
 | 194 |     TextSectionStartSuffix = "\tsegment 'CODE'"; | 
 | 195 |     DataSectionStartSuffix = "\tsegment 'DATA'"; | 
 | 196 |     SectionEndDirectiveSuffix = "\tends\n"; | 
 | 197 |   } | 
| Bill Wendling | cb90099 | 2007-01-16 09:29:17 +0000 | [diff] [blame] | 198 |  | 
 | 199 |   AssemblerDialect = Subtarget->getAsmFlavor(); | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 200 | } | 
| Chris Lattner | afbfded | 2006-10-05 02:43:52 +0000 | [diff] [blame] | 201 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 202 | bool X86TargetAsmInfo::LowerToBSwap(CallInst *CI) const { | 
 | 203 |   // FIXME: this should verify that we are targetting a 486 or better.  If not, | 
 | 204 |   // we will turn this bswap into something that will be lowered to logical ops | 
 | 205 |   // instead of emitting the bswap asm.  For now, we don't support 486 or lower | 
 | 206 |   // so don't worry about this. | 
 | 207 |    | 
 | 208 |   // Verify this is a simple bswap. | 
 | 209 |   if (CI->getNumOperands() != 2 || | 
 | 210 |       CI->getType() != CI->getOperand(1)->getType() || | 
| Chris Lattner | 42a7551 | 2007-01-15 02:27:26 +0000 | [diff] [blame] | 211 |       !CI->getType()->isInteger()) | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 212 |     return false; | 
 | 213 |    | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 214 |   const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); | 
 | 215 |   if (!Ty || Ty->getBitWidth() % 16 != 0) | 
| Reid Spencer | a54b7cb | 2007-01-12 07:05:14 +0000 | [diff] [blame] | 216 |     return false; | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 217 |    | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 218 |   // Okay, we can do this xform, do so now. | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 219 |   const Type *Tys[] = { Ty, Ty }; | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 220 |   Module *M = CI->getParent()->getParent()->getParent(); | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 221 |   Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 2); | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 222 |    | 
 | 223 |   Value *Op = CI->getOperand(1); | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 224 |   Op = new CallInst(Int, Op, CI->getName(), CI); | 
 | 225 |    | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 226 |   CI->replaceAllUsesWith(Op); | 
 | 227 |   CI->eraseFromParent(); | 
 | 228 |   return true; | 
 | 229 | } | 
 | 230 |  | 
 | 231 |  | 
 | 232 | bool X86TargetAsmInfo::ExpandInlineAsm(CallInst *CI) const { | 
 | 233 |   InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue()); | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 234 |   std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints(); | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 235 |    | 
 | 236 |   std::string AsmStr = IA->getAsmString(); | 
 | 237 |    | 
 | 238 |   // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a" | 
 | 239 |   std::vector<std::string> AsmPieces; | 
 | 240 |   SplitString(AsmStr, AsmPieces, "\n");  // ; as separator? | 
 | 241 |    | 
 | 242 |   switch (AsmPieces.size()) { | 
 | 243 |   default: return false;     | 
 | 244 |   case 1: | 
 | 245 |     AsmStr = AsmPieces[0]; | 
 | 246 |     AsmPieces.clear(); | 
 | 247 |     SplitString(AsmStr, AsmPieces, " \t");  // Split with whitespace. | 
 | 248 |      | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 249 |     // bswap $0 | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 250 |     if (AsmPieces.size() == 2 &&  | 
 | 251 |         AsmPieces[0] == "bswap" && AsmPieces[1] == "$0") { | 
 | 252 |       // No need to check constraints, nothing other than the equivalent of | 
 | 253 |       // "=r,0" would be valid here. | 
 | 254 |       return LowerToBSwap(CI); | 
 | 255 |     } | 
 | 256 |     break; | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 257 |   case 3: | 
| Reid Spencer | 4785781 | 2006-12-31 05:55:36 +0000 | [diff] [blame] | 258 |     if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 && | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 259 |         Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && | 
 | 260 |         Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { | 
 | 261 |       // bswap %eax / bswap %edx / xchgl %eax, %edx  -> llvm.bswap.i64 | 
 | 262 |       std::vector<std::string> Words; | 
 | 263 |       SplitString(AsmPieces[0], Words, " \t"); | 
 | 264 |       if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { | 
 | 265 |         Words.clear(); | 
 | 266 |         SplitString(AsmPieces[1], Words, " \t"); | 
 | 267 |         if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") { | 
 | 268 |           Words.clear(); | 
 | 269 |           SplitString(AsmPieces[2], Words, " \t,"); | 
 | 270 |           if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" && | 
 | 271 |               Words[2] == "%edx") { | 
 | 272 |             return LowerToBSwap(CI); | 
 | 273 |           } | 
 | 274 |         } | 
 | 275 |       } | 
 | 276 |     } | 
 | 277 |     break; | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 278 |   } | 
 | 279 |   return false; | 
 | 280 | } |